Hadoop 序列化与 HDFS 连接:从入门到踩坑全记录

一、依赖缺失与类路径错误

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-clientwoodstox-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。若没有,手动启动:

    bash 复制代码
    hdfs --daemon start datanode

    或重启整个 HDFS:

    bash 复制代码
    stop-dfs.sh && start-dfs.sh

    如果 DataNode 反复退出,查看日志($HADOOP_HOME/logs/hadoop-*-datanode-*.log),常见处理:

    • Incompatible clusterIDs:清理 DataNode 数据目录(实验环境):

      bash 复制代码
      rm -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 确认无残留进程即可。生产环境请勿随意执行,应由管理员操作。


八、总结与避坑指南

  1. 依赖要完整 :使用 hadoop-client 或确保 hadoop-commonhadoop-hdfs-clientwoodstox-core 均已引入。

  2. 路径要规范 :Windows 本地路径使用 file:///D:/... 格式;配置文件中的目录用正斜杠,目录需预先创建。

  3. 环境变量硬编码 :所有节点的 hadoop-env.sh 必须显式设置 JAVA_HOME,这是最常见的启动失败根源。

  4. 主机名互通 :所有节点(包括 Windows 客户端)必须能通过主机名互相 ping 通,/etc/hostshosts 文件要配置完整。

  5. 配置文件更新 :升级 Hadoop 版本后注意废弃项(如 slavesworkers)。

  6. 安全模式与 DataNode:第一次启动或异常关机后,记得检查安全模式,确认 DataNode 存活再进行写入操作。

  7. 权限声明 :用 root 启动实验集群时,务必在 hadoop-env.sh 中添加 _USER 变量。

这些错误单看一条似乎都很"低级",但连续出现时非常消磨热情。把全部坑踩完并记录下来,下次再遇到就能秒杀了。希望这篇文章能帮你绕过这些暗礁,顺利跑通 Hadoop 序列化实验!