一、依赖缺失与类路径错误
1. NoClassDefFoundError: com/ctc/wstx/io/InputBootstrapper
现象
Exception in thread "main" java.lang.NoClassDefFoundError: com/ctc/wstx/io/InputBootstrapper
Caused by: java.lang.ClassNotFoundException: com.ctc.wstx.io.InputBootstrapper
原因
Hadoop 客户端解析 XML 配置文件需要 Woodstox 库,但项目未引入该依赖。
解决
Maven 项目在 pom.xml 中添加:
XML
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
<version>5.4.0</version>
</dependency>
更省心的方式是直接引入完整客户端:
XML
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>你的Hadoop版本</version>
</dependency>
若使用 Gradle 或手动管理 jar,记得把 hadoop-client 或 woodstox-core 放入 classpath。
2. UnsupportedFileSystemException: No FileSystem for scheme "hdfs"
现象
XML
org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for scheme "hdfs"
原因
虽然添加了 hadoop-common,但缺少 HDFS 客户端的具体实现(hadoop-hdfs-client),无法识别 hdfs:// 协议。
解决
确认项目中已包含:
XML
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs-client</artifactId>
<version>3.3.6</version>
</dependency>
如果 Maven 仓库网络不佳,可直接下载对应 jar 并添加到 Module 的依赖中。
二、文件路径与配置文件错误
3. FileNotFoundException: 本地文件路径解析错误
现象
XML
java.io.FileNotFoundException: File E:Hadoop/testupload.txt
代码里明明写的是 d:/testupload.txt,却变成了带冒号的错误路径。
原因
Hadoop 的 Path 在 Windows 下若不加协议前缀,可能被当成相对路径或解析错误。
解决
使用标准 URI 格式:new Path("file:///D:/testupload.txt")。
或者用 Java 的 File 生成 URI:
XML
new Path(new File("D:/testupload.txt").toURI().toString());
4. 启动时报"JAVA_HOME is not set"
现象
执行 start-dfs.sh 时,从节点上出现 Error: JAVA_HOME is not set and could not be found.
原因
Hadoop 脚本通过 SSH 远程执行命令,不会加载 .bashrc 或 /etc/profile 中的环境变量。
解决
在所有节点的 $HADOOP_HOME/etc/hadoop/hadoop-env.sh 中硬编码 Java 路径:
bash
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-2.el7_9.x86_64
可以用 readlink -f $(which java) 找到完整 JDK 路径,取上两级目录作为 JAVA_HOME(确保该目录下有 bin/java)。
5. "bin/java is not executable"
现象
bash
bin/java: No such file or directory
或提示 bin/java 不可执行。
原因
JAVA_HOME 错误地指向了 JRE 目录(没有 bin/java),或路径本身不存在。
解决
-
安装完整 JDK:
yum install java-1.8.0-openjdk-devel -
使用
readlink -f $(which java)找到真实路径,例如/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-2.el7_9.x86_64/jre/bin/java,则JAVA_HOME应设为/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-2.el7_9.x86_64(即去掉/jre/bin/java)。
6. Hadoop 3.x 使用 slaves 文件导致从节点无法启动
现象
从节点没有 DataNode 进程,NameNode 日志提示找不到 slave。
原因
Hadoop 3.x 已经用 workers 文件替代了 slaves。
解决
删除或备份旧的 slaves,在 $HADOOP_HOME/etc/hadoop/ 下创建 workers,每行写一个从节点主机名:
bash
echo -e "slave1\nslave2" > workers
7. 数据目录不存在,DataNode 启动失败
现象
DataNode 日志提示 Directory /usr/local/hadoop-3.3.6/data/datanode does not exist。
原因
hdfs-site.xml 中配置的数据目录未预先创建,Hadoop 不会自动创建多级目录。
解决
在所有节点手动创建:
bash
mkdir -p /usr/local/hadoop-3.3.6/data/{namenode,datanode,tmp}
三、NameNode 安全模式与 DataNode 运行问题
8. SafeModeException: Name node is in safe mode
现象
bash
org.apache.hadoop.hdfs.server.namenode.SafeModeException:
Cannot create file /files/info.txt. Name node is in safe mode.
原因
HDFS 启动后会进入一段安全模式,等待 DataNode 上报足够的数据块。此时禁止写入。
解决
在 NameNode 所在节点手动退出:
bash
hdfs dfsadmin -safemode leave
用 hdfs dfsadmin -safemode get 检查,返回 Safe mode is OFF 即可。
9. 0 datanode(s) running ------ 写入时找不到 DataNode
现象
bash
File /files/info.txt could only be written to 0 of the 1 minReplication nodes.
There are 0 datanode(s) running and 0 node(s) are excluded in this operation.
原因
DataNode 进程未启动,或启动后因 clusterID 不匹配 、权限不足 、网络不通 等原因挂掉。
解决
-
首先检查进程:
jps应显示DataNode。若没有,手动启动:bashhdfs --daemon start datanode或重启整个 HDFS:
bashstop-dfs.sh && start-dfs.sh如果 DataNode 反复退出,查看日志(
$HADOOP_HOME/logs/hadoop-*-datanode-*.log),常见处理: -
-
Incompatible clusterIDs:清理 DataNode 数据目录(实验环境):
bashrm -rf /tmp/hadoop-*/dfs/data/current hdfs namenode -format start-dfs.sh -
权限问题:确保数据目录属主是启动用户,且有读写权限。
-
主机名解析:确保 DataNode 能 ping 通 NameNode 的主机名。
-
-
最后通过
hdfs dfsadmin -report确认 Live datanodes ≥ 1。
重要提示 :DataNode 是独立守护进程,不会随 Java 程序启动而自动运行,必须事先在集群节点上启动。
四、主机名解析与集群通信
10. UnknownHostException: master
现象
Windows 上的 Java 程序连接完全分布式集群时:
bash
java.net.UnknownHostException: master
原因
Windows 无法将 master 解析为 Linux 服务器的 IP。
解决
在 Windows 的 C:\Windows\System32\drivers\etc\hosts 文件中添加:
bash
192.168.1.100 master
或在代码中直接用 IP:
bash
FileSystem.get(new URI("hdfs://192.168.1.100:9000"), conf, "root");
11. ssh: Could not resolve hostname slave1
现象
启动从节点或 SCP 传输时,提示无法解析 slave1。
原因
主节点不能解析从节点的主机名。
解决
在所有节点的 /etc/hosts 中添加完整的集群主机映射:
bash
192.168.1.100 master
192.168.1.101 slave1
192.168.1.102 slave2
并确保已配置 SSH 免密登录(ssh-copy-id)。
12. Slave 节点 jps 只有 Jps,无 DataNode
原因
可能原因:① 使用了废弃的 slaves 文件;② SSH 免密未配;③ 从节点 hadoop-env.sh 未设置 JAVA_HOME;④ 从节点无法解析 master 主机名。
解决
逐一排查:
-
改用
workers文件 -
配置 SSH 免密
-
在所有节点的
hadoop-env.sh中强制写入JAVA_HOME -
在从节点
/etc/hosts中添加 master 映射
五、权限与安全设置
13. root 用户启动被拒:HDFS_NAMENODE_USER not defined
现象
bash
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation.
原因
Hadoop 默认不允许 root 直接启动守护进程,需显式声明允许的用户。
解决
在 hadoop-env.sh 末尾添加(仅限实验环境):
bash
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
生产环境务必创建普通用户(如 hadoop)并赋权。
六、版本与工具适配
14. IDEA 社区版无法安装 Big Data Tools 插件
现象
社区版 IDEA 搜索不到 Big Data Tools 或提示不支持。
原因
该插件仅限 Ultimate 版。
替代方案
-
浏览器直接访问
http://namenode:9870查看 HDFS -
IDEA 内嵌终端使用
hdfs dfs命令 -
编写 Java 代码操作 HDFS
-
使用免费客户端如 HDFS Explorer
15. Windows 与 Linux 集群 Hadoop 版本不一致
现象
Windows 开发环境使用 Hadoop 3.3.6,集群却是 2.10.2,导致 RPC 协议不匹配。
解决
将集群升级到与开发环境一致的 3.3.6 版本(下载安装包,复用配置文件,重新格式化 NameNode)。
七、实验收尾:需要手动关闭 DataNode 吗?
个人实验环境强烈建议手动关闭。DataNode 等守护进程会持续占用系统资源,直接关机可能导致下次启动时 NameNode 长时间停留在安全模式。执行:
bash
stop-dfs.sh
并用 jps 确认无残留进程即可。生产环境请勿随意执行,应由管理员操作。
八、总结与避坑指南
-
依赖要完整 :使用
hadoop-client或确保hadoop-common、hadoop-hdfs-client、woodstox-core均已引入。 -
路径要规范 :Windows 本地路径使用
file:///D:/...格式;配置文件中的目录用正斜杠,目录需预先创建。 -
环境变量硬编码 :所有节点的
hadoop-env.sh必须显式设置JAVA_HOME,这是最常见的启动失败根源。 -
主机名互通 :所有节点(包括 Windows 客户端)必须能通过主机名互相 ping 通,
/etc/hosts或hosts文件要配置完整。 -
配置文件更新 :升级 Hadoop 版本后注意废弃项(如
slaves→workers)。 -
安全模式与 DataNode:第一次启动或异常关机后,记得检查安全模式,确认 DataNode 存活再进行写入操作。
-
权限声明 :用 root 启动实验集群时,务必在
hadoop-env.sh中添加_USER变量。
这些错误单看一条似乎都很"低级",但连续出现时非常消磨热情。把全部坑踩完并记录下来,下次再遇到就能秒杀了。希望这篇文章能帮你绕过这些暗礁,顺利跑通 Hadoop 序列化实验!