欢迎光临
我们一直在努力

Hadoop 3.3.6 开发实战:从 JDK 版本到集群启动的常见坑与解决方案

一文搞定 Windows + Linux 混合开发环境下的 Hadoop 兼容性、启动失败、DataNode 掉线等问题

前言

最近在 Windows 环境下使用 Hadoop 3.3.6 进行开发,同时连接 Linux 集群进行测试,遇到了形形色色的问题——WebHDFS 页面报错、stop-all.sh 无法停止、DataNode 启动后消失、编译好的 Jar 包跑不起来……这些“经典”问题几乎把 Hadoop 的常见坑踩了个遍。
经过一番折腾,终于把所有问题梳理清楚,这里整理成文,希望能帮助遇到类似情况的朋友快速定位并解决。


一、最致命的问题:JDK 版本不兼容

现象一:WebHDFS 页面无法浏览文件

访问 http://localhost:9870/explorer.html 时,页面报错:

Failed to retrieve data from /webhdfs/v1/?op=LISTSTATUS: Server Error

查看 NameNode 日志,发现异常堆栈往往指向 javax.activation 相关类缺失或版本错误。

现象二:运行 Jar 包时抛出 UnsupportedClassVersionError

class file version 61.0 (Java 17) … only supports 52.0 (Java 8)

根本原因

Hadoop 3.3.6 官方推荐 JDK 8 或 JDK 11,但如果你的系统默认 Java 是 JDK 17/18 等高版本,就会导致:

  • WebHDFS 所需的 JAXB/Activation 模块在高版本 JDK 中被移除或变化,无法正常工作。

  • 编译时使用高版本 JDK 生成的字节码,无法在低版本 JVM 上运行。

解决方案(二选一)

✅ 方案一:为 Hadoop 单独指定低版本 JDK(推荐)
  • 下载并安装 JDK 8 或 JDK 11(如 Adoptium 或 Oracle 版本),记住安装路径,例如 D:\\Java\\jdk1.8.0_202。

  • 编辑 $HADOOP_HOME\\etc\\hadoop\\hadoop-env.cmd(Windows)或 hadoop-env.sh(Linux),显式设置:

    set JAVA_HOME=D:\\Java\\jdk1.8.0_202

    export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64

  • 重启 Hadoop 服务,刷新 Web UI,错误消失。

  • ✅ 方案二:临时修补(不降 JDK)

    将 activation-1.1.1.jar 复制到 $HADOOP_HOME\\share\\hadoop\\common\\lib\\ 并重启服务。
    注意:此方法可能不彻底,仍可能遇到其他兼容性问题,建议优先采用方案一。


    二、启动/停止服务时的权限与变量问题

    问题 1:stop-all.sh 报错 “but there is no HDFS_NAMENODE_USER defined”

    Hadoop 3.x 安全机制默认禁止 root 直接启动守护进程,但实验环境往往用 root 操作,此时需在配置文件中声明允许。

    解决方法:

    • 编辑 $HADOOP_HOME/etc/hadoop/hadoop-env.sh,添加:

      export HDFS_NAMENODE_USER=root
      export HDFS_DATANODE_USER=root
      export HDFS_SECONDARYNAMENODE_USER=root

    • 编辑 $HADOOP_HOME/etc/hadoop/yarn-env.sh,添加:

      export YARN_RESOURCEMANAGER_USER=root
      export YARN_NODEMANAGER_USER=root

    然后重新执行停止脚本即可。

    问题 2:JAVA_HOME is not set 或 bin/java is not executable

    Hadoop 启动脚本通过 SSH 远程执行时,不会继承用户的环境变量,因此必须在 hadoop-env.sh 中硬编码完整的 JDK 路径。

    正确做法:

    • 在 hadoop-env.sh 中强制设置:

      export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64

      (务必指向包含 bin/java 的目录,不能是 JRE 目录)

    • 如果找不到 JDK 绝对路径,可用 readlink -f $(which java) 获取真实路径,再取上两级目录。


    三、集群通信与节点启动失败

    问题 1:UnknownHostException: master 或 slave

    Windows 开发机无法解析 Linux 集群的主机名,或 Linux 节点之间无法互相解析。

    解决方法:

    • Windows 端:编辑 C:\\Windows\\System32\\drivers\\etc\\hosts,添加集群所有节点的 IP 和主机名映射,例如:

      192.168.1.100 master
      192.168.1.101 slave1
      192.168.1.102 slave2

    • Linux 节点:同样在 /etc/hosts 中添加所有节点的映射,确保 ping master 和 ping slave1 能通。

    • 若使用 IP 直连,可在 core-site.xml 中将 fs.defaultFS 设为 hdfs://192.168.1.100:9000 来临时绕过主机名解析。

    问题 2:Slave 节点 jps 只显示 Jps,没有 DataNode

    常见原因:

  • 使用了 Hadoop 3.x 已废弃的 slaves 文件(应改用 workers)。

  • SSH 免密登录未配置,导致 master 无法启动 slave 上的进程。

  • slave 上的 JAVA_HOME 未在 hadoop-env.sh 中设置。

  • slave 无法解析 master 主机名。

  • 排查流程:

    • 删除或备份旧的 slaves,新建 workers 文件,每行一个从节点主机名。

    • 配置免密 SSH:ssh-keygen + ssh-copy-id slave1。

    • 检查所有节点的 hadoop-env.sh 中是否都有 JAVA_HOME 硬编码。

    • 检查所有节点的 /etc/hosts 是否包含 master 映射。

    问题 3:DataNode 进程存在,但上传文件时报 “0 datanode(s) running”

    可能原因
    • 之前格式化过 NameNode,但未清理 DataNode 数据目录,导致 clusterID 不一致。

    • 防火墙阻断了 DataNode 端口(如 9866)。

    • 磁盘空间不足。

    • 副本数 dfs.replication 设置大于可用 DataNode 数量(伪分布式必须设为 1)。

    解决办法
  • 停止集群,删除 DataNode 数据目录(默认为 dfs.datanode.data.dir 配置的路径,如 /tmp/hadoop-root/dfs/data)。

  • 重新格式化 NameNode:hdfs namenode -format。

  • 启动集群:start-dfs.sh。

  • 用 hdfs dfs -mkdir /test 和 -put 测试写入是否正常。

  • 若为单节点伪分布式,确保 hdfs-site.xml 中设置:

    <property>
    <name>dfs.replication</name>
    <value>1</value>
    </property>


  • 四、开发环境中的配置与路径问题

    1. IDEA 社区版无法安装 Big Data Tools 插件

    该插件仅支持 Ultimate 版,替代方案:

    • 直接用浏览器访问 http://localhost:9870 浏览 HDFS。

    • 在 IDEA 终端使用 hdfs dfs -ls / 等命令操作。

    • 编写 Java 代码通过 FileSystem API 操作。

    • 使用免费客户端如 HDFS Explorer。

    2. 本地文件路径解析错误

    Windows 下,代码中 new Path("d:/testupload.txt") 可能被错误解析为 HDFS 相对路径,导致 FileNotFoundException。

    正确写法:

    • 使用完整 URI:new Path("file:///D:/testupload.txt")

    • 或通过 new File("D:/testupload.txt").toURI().toString() 生成路径。

    3. Hadoop 3.x 弃用 slaves 改用 workers

    升级到 Hadoop 3.x 后,务必删除旧的 slaves 文件,新建 workers 并填写从节点主机名,否则从节点不会启动。

    4. 数据目录未预先创建

    格式化 NameNode 前,确保 dfs.namenode.name.dir 和 dfs.datanode.data.dir 所指向的目录已经存在,否则启动时会报错。
    手动创建:

    mkdir -p /usr/local/hadoop-3.3.6/data/{namenode,datanode,tmp}

    5. 编译版本与运行环境不一致

    • IDEA 中设置 Project SDK 为 JDK 8,Language level 为 8。

    • 在 pom.xml 中强制指定:

      <properties>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
      </properties>

    • 打包后用 javap -verbose YourClass.class | grep major 验证版本号应为 52。


    五、通用排查技巧

    问题现象优先检查项
    WebHDFS 无法访问 检查 hdfs-site.xml 中 dfs.webhdfs.enabled 是否为 true;查看 NameNode 日志
    启动失败 查看 $HADOOP_HOME/logs/ 下最新的 .log 文件,错误堆栈最直接
    从节点未启动 jps 检查进程;检查 SSH 免密;检查 workers 文件;检查 JAVA_HOME
    网络问题 临时关闭防火墙测试,或检查端口是否被占用
    权限问题 确保 HDFS 目录权限,或在 core-site.xml 中设置 hadoop.http.staticuser.user 为你的用户名

    总结

  • JDK 版本是最容易忽视的“隐形杀手”——务必为 Hadoop 单独指定 JDK 8/11,不要依赖系统默认。

  • 环境变量必须硬编码,不要指望 SSH 继承 .bashrc。

  • 主机名解析、数据目录、配置文件格式这些细节,出了问题往往让人头疼,按步骤逐一排查即可。

  • 开发环境(Windows)与集群(Linux)的 Hadoop 大版本必须一致,否则 RPC 协议不兼容,会出现各种神秘错误。

  • 善用日志——Hadoop 的日志信息非常详细,90% 的问题都能从日志中找到线索。

  • 希望这篇文章能帮助大家少踩一些坑。如果你也有其他 Hadoop 实战中的问题,欢迎留言交流!


    如果觉得有用,欢迎点赞、收藏、转发,让更多人看到~

    赞(0)
    未经允许不得转载:171主机测评 » Hadoop 3.3.6 开发实战:从 JDK 版本到集群启动的常见坑与解决方案
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址