Hadoop 3.3.5三节点全分布式集群部署实战与踩坑指南

发布时间:2026/9/16 2:56:14
Hadoop 3.3.5三节点全分布式集群部署实战与踩坑指南 从去年开始我陆陆续续帮团队搭了三四套大数据测试环境用的都是 Hadoop 3.3.5 这个版本。说实话网上关于 Hadoop 部署的教程一抓一大把但很多要么只讲伪分布式要么停留在 照着敲命令 的层面一旦节点数量超过两台各种奇葩问题就全冒出来了。这篇文章不打算重复官方文档而是把我自己在三台物理节点上部署 Hadoop 3.3.5 全分布式集群的完整过程、关键配置项的解释、以及踩坑后的排查思路整理出来给准备入坑或者正在折腾分布式的小伙伴一个参考。Hadoop 3.3.5 是 3.3.x 生命周期里比较稳定的一个发行版相比 3.2 系列它在 YARN 资源管理、RPC 性能、以及 S3A 客户端等方面都有不少改进而且对 JDK 8 和 JDK 11 都做了完整支持这对很多还在沿用 JDK 8 的老团队来说非常友好。如果你正准备从单机模式跨到多节点集群或者之前用的还是 Hadoop 2.x想找一个平衡稳定性和新特性的版本这篇部署实战应该能帮上忙。1. 部署前一定要想清楚的三件事1.1 版本选型为什么用 3.3.5 而不是最新版很多人上来就问为啥不用 Hadoop 3.4.x 或者 4.x我的回答通常是除非你有明确的新特性需求否则在生产或准生产环境里选一个经过大量企业验证的稳定版本永远是对的。Hadoop 3.3.5 属于 3.3 系列的中后期版本修复了很多早期 3.3.0 到 3.3.3 的 bug同时又没有引入太多激进的变化生态兼容性也最好。举几个实际的点它同时兼容 JDK 8 和 JDK 11像我这边团队的老项目还在用 JDK 8可以直接无缝衔接。3.3.5 的 YARN 对 GPU 和 FPGA 调度做了完善虽然我们暂时用不上但边缘业务未来扩展时不用换版本。市面上大部分大数据组件Hive、Spark、Flink、HBase的官方编译包都是基于 Hadoop 3.3 系列做的兼容测试版本匹配最省事。在 NameNode 元数据性能和 RPC 吞吐上3.3.5 相比 3.2.x 有可感知的提升尤其是在小文件较多的场景。1.2 集群规模规划三节点还是五节点正式动手之前先用表格把节点规划敲定这一步看着简单但直接影响后续所有配置。我这次测试环境用了三台物理服务器配置如下节点角色主机名配置部署组件主节点hadoop-master8C16G / 200G 系统盘 1T 数据盘NameNode、ResourceManager、SecondaryNameNode从节点1hadoop-node18C16G / 200G 系统盘 2T 数据盘DataNode、NodeManager从节点2hadoop-node28C16G / 200G 系统盘 2T 数据盘DataNode、NodeManager三节点是学习、开发和测试的最小完整集群形态因为它能跑通 HDFS 副本机制我设置了副本数 2三节点正好满足也能同时验证 YARN 的分布式计算能力。如果你的机器资源紧张第一次可以先在虚机上尝试但内存尽量每台不低于 4G否则后面启动多个守护进程很容易 OOM。不建议在一台物理机上用多个虚拟机模拟分布式很多网络和端口问题会被虚拟化层掩盖等你真正上了物理机又是一堆新坑。1.3 网络与端口规划Hadoop 集群内部节点之间需要互相通信如果跨防火墙部署下面这些端口必须提前确认放通。我在实际部署中经常看到有人配置好所有文件结果 ResourceManager 的 Web 界面死活打不开最终发现是安全组没放行端口。组件端口说明NameNode RPC8020客户端与 NameNode 通信NameNode HTTP UI9870HDFS Web 管理界面SecondaryNameNode HTTP9868辅助 NameNode 的 Web 界面DataNode RPC9867DataNode 与 NameNode 通信DataNode HTTP UI9864DataNode 管理界面ResourceManager IPC8030ResourceManager 内部通信ResourceManager HTTP UI8088YARN Web 管理界面NodeManager IPC8040NodeManager 通信MapReduce JobHistory19888历史作业查看界面提醒一下生产集群的节点之间通信我建议把安全组做到最小化但如果第一次实验部署先把防火墙关掉排查问题会省很多精力。环境稳定后再逐步收紧安全策略。2. 基础环境准备账号、主机名、免密与时序同步2.1 创建专用账号与目录规范Hadoop 依赖的守护进程比较多我强烈不建议用 root 直接跑。root 跑 HDFS 会出现一个很隐蔽的问题DataNode 上传的本地数据块文件默认属主是 root一旦后续需要调整权限或删数据会出现各种奇怪的文件权限错误。我在生产环境里吃过这个亏后面就学乖了任何大数据组件一律用独立账号。useradd -m -s /bin/bash hadoop passwd hadoop mkdir -p /data/hadoop chown -R hadoop:hadoop /data/hadoop目录规划上我会把软件包、数据目录、日志目录分开方便管理和排障/opt/hadoopHadoop 安装目录/data/hadoop/hdfs/nameNameNode 元数据目录/data/hadoop/hdfs/dataDataNode 数据块目录/data/hadoop/logs日志目录2.2 主机名、hosts 映射每台节点都要设置一个有意义的主机名然后统一写进 hosts。这里有个细节hosts 里尽量写入内网 IP 而不是公网 IP否则跨机房网络容易出现延迟高甚至连接超时的问题。# 每台节点分别执行 hostnamectl set-hostname hadoop-master # node1/node2 各自修改对应名字 # 所有节点 /etc/hosts 保持完全一致 cat /etc/hosts EOF 192.168.10.10 hadoop-master 192.168.10.11 hadoop-node1 192.168.10.12 hadoop-node2 EOF2.3 SSH 免密登录配置Hadoop 的启动脚本是通过 SSH 无密码登录远程节点去拉起守护进程的所以主节点必须能免密登录包括自己在内的所有节点。这也是新手最容易卡住的一步。# 在 hadoop-master 上切换到 hadoop 用户 ssh-keygen -t rsa -P -f ~/.ssh/id_rsa # 分发公钥到所有节点包括本机 ssh-copy-id hadoophadoop-master ssh-copy-id hadoophadoop-node1 ssh-copy-id hadoophadoop-node2 # 验证 ssh hadoophadoop-node1 hostname如果你分发完公钥发现仍然要输密码多数是~/.ssh目录权限不对。.ssh目录需要 700 权限authorized_keys需要 600 权限这个坑我帮同事排查过好几回。2.4 时钟同步别让时间差毁掉你的集群Hadoop 的 HDFS 和 YARN 内部对节点间时间一致性有隐性要求尤其是 Kerberos 开启后时间偏差超过一定阈值直接报认证失败。即使不开 Kerberos时间差太大也会导致数据块汇报异常、作业状态混乱等问题。yum install -y chrony # CentOS/Rocky systemctl enable --now chronyd chronyc sources # 确认时间源状态为 *表示已同步没有内部 NTP 服务器的场景就用默认的 CentOS 公共时间源即可。对实验环境来说保证几台机器时间基本一致就行。3. 核心配置详解七个配置文件一次讲透3.1 环境变量与 Java 依赖Hadoop 3.3.5 官方文档说明支持 JDK 8 和 JDK 11我按团队现状选了 JDK 8。这里不建议用 yum 自动安装 JDK因为 yum 拉下来的路径有时候不符合 Hadoop 脚本的默认查找逻辑直接用官方 tar 包最省心。tar -zxf jdk-8u391-linux-x64.tar.gz -C /opt/ tar -zxf hadoop-3.3.5.tar.gz -C /opt/ mv /opt/hadoop-3.3.5 /opt/hadoop chown -R hadoop:hadoop /opt/hadoop cat ~/.bashrc EOF export JAVA_HOME/opt/jdk1.8.0_391 export HADOOP_HOME/opt/hadoop export PATH$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin EOF source ~/.bashrc注意JAVA_HOME要写进 hadoop-env.sh 里面一份。Hadoop 的脚本在通过 SSH 远程执行命令时不一定加载 bashrc但一定会读$HADOOP_HOME/etc/hadoop/hadoop-env.sh。我之前遇到过本地执行hdfs命令正常start-dfs.sh远程节点却报 JAVA_HOME not found就是这个问题。3.2 workers 文件决定从节点都有谁Hadoop 3.x 里没有 slaves 文件改成了 workers。这个文件里列出所有 DataNode 和 NodeManager 所在的节点主机名。# $HADOOP_HOME/etc/hadoop/workers hadoop-master hadoop-node1 hadoop-node2注意一个容易踩的坑如果主节点也想跑 DataNode单 master 时很常见就在 workers 里写上 master 自己的主机名。如果不想让 master 承担存储压力就不写它。两种方式都可以没有规定说 master 不能同时做 DataNode。3.3 core-site.xml集群入口与临时目录这是客户端和集群通信时的核心入口配置主要定义默认文件系统、NameNode 的 RPC 地址以及 Hadoop 临时目录。configuration property namefs.defaultFS/name valuehdfs://hadoop-master:8020/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property property nameha.zookeeper.quorum/name valuehadoop-master:2181,hadoop-node1:2181,hadoop-node2:2181/value /property /configurationhadoop.tmp.dir默认值是/tmp/hadoop-${user.name}如果不改系统重启后/tmp被清理NameNode 会因找不到元数据而启动失败。这可以说是新手最常见的故障之一我见过太多人格式化后能跑重启一次就挂掉的案例。ha.zookeeper.quorum这里先写上 Zookeeper 的地址本篇文章不展开 HA 搭建但提前把配置项写上后续如果要做高可用不用再改分布式文件系统核心配置。3.4 hdfs-site.xml副本、元数据与 Web 端口这个文件是 HDFS 的核心配置。三节点集群我推荐把副本数设置为 2既能保证数据安全又不会因为副本数等于节点数导致某个节点故障就完全无法读取数据。configuration property namedfs.replication/name value2/value /property property namedfs.namenode.name.dir/name valuefile:///data/hadoop/hdfs/name/value /property property namedfs.datanode.data.dir/name valuefile:///data/hadoop/hdfs/data/value /property property namedfs.namenode.secondary.http.address/name valuehadoop-master:9868/value /property property namedfs.namenode.http-address/name valuehadoop-master:9870/value /property property namedfs.datanode.http.address/name value0.0.0.0:9864/value /property property namedfs.permissions.enabled/name valuetrue/value /property /configuration关于dfs.datanode.data.dir我有一个建议如果节点有多个数据盘在这个配置项里用逗号分隔写多个目录HDFS 会自动做跨目录负载均衡。我这里只有一块数据盘所以就写了一个目录但思想是一样的。dfs.permissions.enabled默认就是 true我显式写出来是为了提醒自己开启权限后客户端访问文件必须关注目录 OWNER 和权限位很多新手在 HDFS 上创建目录然后莫名其妙 PUT 失败多数是权限模式太严格。3.5 yarn-site.xml资源调度与容器管理YARN 是 Hadoop 的计算调度层ResourceManager 和 NodeManager 的配置都在这个文件里。configuration property nameyarn.resourcemanager.hostname/name valuehadoop-master/value /property property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.nodemanager.aux-services.mapreduce_shuffle.class/name valueorg.apache.hadoop.mapred.ShuffleHandler/value /property property nameyarn.nodemanager.resource.memory-mb/name value8192/value /property property nameyarn.nodemanager.resource.cpu-vcores/name value4/value /property property nameyarn.scheduler.minimum-allocation-mb/name value512/value /property property nameyarn.scheduler.maximum-allocation-mb/name value4096/value /property /configuration很多人在部署时内存配置乱写直接把yarn.nodemanager.resource.memory-mb设成节点总内存 16G结果 NodeManager 启动后把机器内存吃满或者运行 MapReduce 时 Container 怎么也不够用。这块的合理设置逻辑是给操作系统和 DataNode 预留 20% 左右的内存剩余的内存才作为 NodeManager 可分配资源。比如节点 16G 内存我设置 8192MB 或 10240MB 是比较稳妥的。yarn.nodemanager.aux-services必须设置成mapreduce_shuffle它的作用相当于 MapReduce 中间数据传输的辅助服务如果不配跑 MapReduce 作业时 Task 之间无法 Shuffle作业会一直卡在 Map 阶段。3.6 mapred-site.xml决定计算框架configuration property namemapreduce.framework.name/name valueyarn/value /property property nameyarn.app.mapreduce.am.env/name valueHADOOP_MAPRED_HOME${HADOOP_HOME}/value /property property namemapreduce.map.memory.mb/name value1024/value /property property namemapreduce.reduce.memory.mb/name value1024/value /property /configurationmapreduce.framework.name设置为 yarn表示作业提交到 YARN 集群上执行。如果写 local则退化为本地模式即使你有三台节点也只会在本机跑失去了分布式计算的意义。mapreduce.map.memory.mb和reduce.memory.mb的默认值是 1024MB如果你修改了 YARN 单 Container 的最大内存这里要注意同步修改否则可能会出现作业请求的内存超过 YARN 限制Map Task 直接失败。3.7 配置文件分发主节点上写完所有配置后把整个 hadoop 目录同步到从节点注意目录所属用户要保留 hadoop:# 在 hadoop-master 上执行 rsync -av /opt/hadoop/ hadoophadoop-node1:/opt/hadoop/ rsync -av /opt/hadoop/ hadoophadoop-node2:/opt/hadoop/分发完配置后最好分别登录从节点确认一下 JAVA_HOME 和 HADOOP_HOME 是否设置正确。4. 格式化 NameNode、启动与首次验证4.1 NameNode 格式化一次性的操作别乱敲NameNode 格式化就是初始化 HDFS 的元数据目录生成current/VERSION文件里面记录了一个唯一的 clusterID。这一步只能在主节点执行而且只在第一次部署时执行一次。# 在 hadoop-master 上hadoop 用户执行 hdfs namenode -format执行后会在控制台看到successfully formatted字样并且会打印出生成的 storage directory。需要格外注意的是格式化一次之后不要因为 DataNode 启动失败就反复重新格式化。我在下文会专门讲由 clusterID 不一致引发的故障那是一个很典型的连环坑。4.2 启动顺序与脚本说明启动顺序很重要先 HDFS再 YARN。Hadoop 提供了合并启动脚本start-all.sh但我更推荐分开启动这样环境变量或配置有问题时能快速定位是存储层还是调度层的问题。# 启动 HDFS会在 workers 所列的所有节点拉起 DataNode start-dfs.sh # 启动 YARN start-yarn.sh启动完成后在主节点用jps查看 Java 进程节点预期进程hadoop-masterNameNode、SecondaryNameNode、ResourceManagerhadoop-node1DataNode、NodeManagerhadoop-node2DataNode、NodeManager4.3 Web 界面与上传下载验证进程都起来后浏览器访问http://hadoop-master:9870应该能看到 HDFS 的 Web 界面DataNode 列表里会显示两个活跃节点。访问http://hadoop-master:8088能看到 YARN 的 ResourceManager 界面如果 Active Nodes 数量为 2说明 NodeManager 正常心跳。接下来做一轮完整的功能验证包括建目录、上传文件、读文件# 创建用户目录 hdfs dfs -mkdir -p /user/hadoop # 测试数据上传 echo hadoop 3.3.5 distributed cluster test.txt hdfs dfs -put test.txt /user/hadoop/ # 读取验证 hdfs dfs -cat /user/hadoop/test.txt # 查看数据块位置验证是否分布在不同节点 hdfs fsck /user/hadoop/test.txt -files -blocks -locationsfsck输出的最后一列能看到每个数据块所在节点正常情况会显示两个不同的 DataNode这证明副本复制成功。4.4 提交第一个 MapReduce 作业如果只是学会上传下载文件那还没完全验证 YARN 的能力。用 Hadoop 自带的 WordCount 跑一轮真正的分布式计算# 准备输入数据目录 hdfs dfs -mkdir -p /wordcount/input hdfs dfs -put /etc/profile /wordcount/input/ # 执行 WordCount hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.5.jar \ wordcount /wordcount/input /wordcount/output # 查看结果 hdfs dfs -cat /wordcount/output/part-r-00000跑到这里你的三节点集群说白已经完整跑通了 HDFS 存储和 YARN 计算两条链路。初次看到 console 里 map 100% 到 reduce 100% 的输出那种感觉还是挺有成就感的。5. 实战中的经典故障从现象到根因的排查链路5.1 NameNode 正常但 DataNode 全部掉线现象start-dfs.sh执行没有报错jps各进程都在但 Web 界面 DataNode 列表为空或者 DataNode 进程启动几秒后自动退出日志里出现Incompatible clusterIDs。根因链路这个坑最常见的出现时机是你在某次启动不成功后重新执行了hdfs namenode -format。NameNode 格式化会生成全新的 clusterID而 DataNode 之前已经用旧的 clusterID 在自己的数据目录里写入了身份标识两边一对比发现不是同一个集群DataNode 就会拒绝注册。解决办法# 停掉所有 HDFS 进程 stop-dfs.sh # 在所有节点的 DataNode 数据目录清空已有数据 # 主节点如果也作为 DataNode 要一并清理 rm -rf /data/hadoop/hdfs/data/* # 只在主节点再次格式化 NameNode hdfs namenode -format # 重新启动 start-dfs.sh这里要特别强调清空数据目录是最后手段只在测试环境里操作。生产环境如果遇到 clusterID 不一致应该把 NameNode 生成的current/VERSION里的 clusterID 手动同步给各个 DataNode 的 VERSION 文件而不是格式化重建元数据否则会丢失文件系统的所有元数据指针。5.2 内存分配不合理导致 NodeManager 无法启动现象start-yarn.sh执行后主节点的 ResourceManager 正常但从节点的 NodeManager 启动失败日志报错类似Maximum allowed allocation ... is less than the minimum。根因链路这个报错一般是你把yarn.scheduler.maximum-allocation-mb设置得比yarn.nodemanager.resource.memory-mb还大或者两者之间的关系没理顺。YARN 调度器要求最大分配不能超过 NodeManager 可用资源如果配置自相矛盾NodeManager 根本无法和 ResourceManager 协商出有效的调度区间。解决办法保持这三个配置项的数值关系yarn.nodemanager.resource.memory-mb 节点可用内存预留系统开销后yarn.scheduler.maximum-allocation-mb≤yarn.nodemanager.resource.memory-mbyarn.scheduler.minimum-allocation-mb≤mapreduce.map.memory.mb我测试环境 16G 内存的节点设置memory-mb10240maximum-allocation-mb8192minimum-allocation-mb512跑 WordCount 和一些常规 Spark 作业都很稳。5.3 客户端提交作业失败上报文件路径与 Shuffle 服务异常现象集群运行正常但从集群外部客户端执行hadoop jar提交作业时报错Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): Permission denied或者ShuffleHandler cannot be found。处理思路这里要区分两个问题。第一个权限拒绝多半是客户端用户不是 hdfs 目录的 owner。解决方式要么把客户端的用户加到集群 hadoop 用户组要么在 HDFS 上给对应用户创建目录并授权hdfs dfs -mkdir -p /user/clientuser hdfs dfs -chown -R clientuser:clientuser /user/clientuser第二个ShuffleHandler 找不到一定是yarn-site.xml里aux-services配置写错了或者服务端修改配置后没有重启 NodeManager。5.4 9864 端口可视化看不到 DataNode 信息现象浏览器访问 DataNode 的 9864 端口页面能打开但一直提示无法连接 NameNode。根因链路这通常不是因为 DataNode 没启动而是 DataNode 所在节点的防火墙没有放行 9864 端口与 8020 端口或者dfs.datanode.http.address配置成了具体的 IP而那个 IP 不是当前节点监听的地址。解决办法在从节点上执行ss -lntp | grep 9864确认监听地址是 0.0.0.0 还是特定 IP。如果显示为特定 IP去hdfs-site.xml里改成0.0.0.0:9864并重启 DataNode。同时确认防火墙放行firewall-cmd --add-port9864/tcp --permanent firewall-cmd --reload6. 集群部署完之后的收尾与扩展思考6.1 配置日志聚合与回收站一个真正好用的集群不能只停留在最快的部署链路。我会在部署收尾时顺手做三件事它们看起来不起眼但在日后的使用中能省下大量排障时间。第一件事是开启 YARN 日志聚合否则 MapReduce 作业记录散落在各个 NodeManager 的本地目录每次看日志都要逐个节点去翻非常痛苦property nameyarn.log-aggregation-enable/name valuetrue/value /property property nameyarn.log-aggregation.retain-seconds/name value604800/value /property第二件事是开启 HDFS 回收站给误删除留一条后悔药property namefs.trash.interval/name value1440/value /property第三件事是把dfs.datanode.data.dir最小可用空间阈值设置好防止某块磁盘被写满引发写入异常。6.2 单 NameNode 的瓶颈与高可用方向三节点集群是学习分布式系统的绝佳起点但如果你准备让它承担更多的业务压力很快会遇到单点瓶颈。NameNode 内存决定了整个集群能承载的文件和目录数量单台 NameNode 故障会导致整个 HDFS 不可用而且元数据恢复的时间随着文件数量增长而成倍增加。后续要往 HA 方向扩展核心是引入 Zookeeper 集群和 JournalNode 集群让两个 NameNode 通过共享 edit log 保证元数据同步再配合 ZKFC 实现自动故障切换。本篇文章不展开但你在规划服务器资源时提前预留 Zookeeper 节点的资源未来平滑扩展会轻松很多。6.3 我对这套集群配置的最终评估如果你是完全的新手照着上面这套配置在不考虑网络异常的情况下通常两个小时内可以跑通一个三节点的 Hadoop 3.3.5 集群。从我实际使用的感受来说3.3.5 在稳定性上确实对得起经典版本四个字运行了大半年没有出现一次 PHP 式的玄学崩溃YARN 服务重启也很干净。最后分享一个我个人的小习惯每次修改完配置不要急着 start先用hdfs dfsadmin -report检查存储节点状态再用yarn node -list检查计算节点状态。这两个命令输出的信息非常直接比打开 Web UI 点按钮高效得多。集群运维是个细水长流的活儿把每一步的基础打扎实了后面跑业务、优化调度、做监控才有底气。