Hadoop集群运行实战:核心配置、启停验证与高频故障排查 简介第5章 Hadoop集群运行.pdf 是一份围绕Hadoop集群运维核心操作的实验型学习资料适配1X大数据相关认证的技能训练需求。文档以实验任务为主线从NameNode与DataNode格式化配置切入依次覆盖清零数据与删除工作目录等格式化注意事项、Java进程查看jps、HDFS报告生成hdfs dfsadmin -report、浏览器查看节点状态以及stop-all.sh停止集群的完整流程同时给出服务器集群3个以上节点、CentOS 7.4环境等最低配置建议。全文仅1个PDF文件大小1.33MB内容由实验目的、要求、环境与过程四部分构成步骤配有命令示例与输出结果能帮助读者理清首次格式化与重新格式化的差异适合已具备基础集群搭建经验的读者用于巩固运维要点。目前已有203人学习可作为Hadoop集群日常管理与排错思路的便捷参考资料。1. 从“第5章 Hadoop集群运行”说起集群跑不起来前面的理论等于白看“第5章 Hadoop集群运行”是很多大数据教材里承上启下的一章前面讲了HDFS和MapReduce原理后面要接数据分析和课程设计偏偏这一步卡住了大批人。原因在于集群运行这件事的难点从来不在敲那几条启动命令而在三件事上集群形态选没选对、四个核心配置文件是否互相匹配、启动之后能不能用正确的指标确认它真的在干活。这篇文章就顺着一套可复现的流程展开从选型讲到配置再从启停命令讲到高频故障排查最后一章给你一个能持续复用的运行检查方法。适合刚在虚拟机里搭好伪分布式的学生也适合准备把课程设计直接跑在完全分布式集群上的实践者。先把集群跑起来后面再谈优化和调参才算真正入门。2. 跑集群之前先确认形态和环境别急着敲 start-dfs.sh2.1 三种集群形态怎么选伪分布式、完全分布式还是 HA很多读者拿到“第5章 Hadoop集群运行”这个标题时第一反应是找一套命令从头敲到尾。但集群形态没定后面的配置全是白做。日常用得最多的是三种伪分布式、完全分布式、HA 高可用。伪分布式适合单机学习和跑通 HDFS 与 MapReduce 的最小链路所有进程挤在同一台机器上配置最简单也是入门时最容易成功的一种。完全分布式才是真正意义上的“集群运行”至少三台机器NameNode 和 ResourceManager 单独一台DataNode 和 NodeManager 分布在其余节点上这也是大多数课程设计和毕业设计采用的方案。HA 高可用则是在完全分布式基础上引入两个 NameNode 和 ZooKeeper 来做自动故障切换文件写入之前先写 JournalNode 集群这是生产环境的标配。如果你在简历或面试题里聊到 Hadoop 集群搭建面试官默认会追问 HA 的原理和 ZooKeeper 在其中扮演的角色所以哪怕暂时用不上也要知道 HA 和普通完全分布式的差别在哪。下面的表把这三种形态的差异列出来方便你对着自己的机器数做决定集群形态节点数量核心进程分布适用场景典型代价伪分布式1 台所有进程都在本机学习、功能验证无法模拟网络故障和数据分布完全分布式3 台及以上NameNode/ResourceManager 独立DataNode 分散课程设计、中小规模数据处理需要多台机器或虚拟机HA 高可用5 台及以上双 NameNode JournalNode ZooKeeper生产环境、7×24 运行部署复杂度高资源消耗大如果你手头只有一台笔记本电脑又想体验接近真实的效果常见做法是先在 VMware 或 VirtualBox 里装三台 CentOS 虚拟机每台分配 2GB 内存和双核 CPU然后按完全分布式去配。虚拟机上安装 Hadoop 的坑比物理机多主要体现在内存不足和 IP 变化后面避坑章会专门讲。2.2 基础环境核查与免密登录起集群前必做的三件事环境检查是集群运行里最容易翻车的环节。第一次搭建时我跳过 hostname 配置直接改 IP结果 DataNode 注册不上 NameNode日志里全是 UnknownHost后来才意识到主机名和 hosts 映射必须先行。按照下面的顺序做每一步都有明确目的。第一步固定主机名和 hosts 映射。/etc/hostname写上节点名/etc/hosts里把所有节点的 IP 和主机名对应写全不要只写本机。# 在每台节点上执行以 node01 为例 hostnamectl set-hostname node01 cat /etc/hosts EOF 192.168.10.10 node01 192.168.10.11 node02 192.168.10.12 node03 EOF这里的关键是把 IP 写在 hosts 文件里避免 Hadoop 内部通过 DNS 解析主机名时拿到 127.0.0.1。配置完成后用ping node02验证一下映射是通的这一步能省掉后面大量连接超时的问题。第二步配置 SSH 免密登录。Hadoop 的启停脚本需要在节点间用 SSH 分发命令如果每次都要求输入密码start-dfs.sh会卡在无交互的终端里直接失败。# 在 node01 上生成密钥并分发到所有节点包括自己 ssh-keygen -t rsa -P ssh-copy-id node01 ssh-copy-id node02 ssh-copy-id node03 # 验证免密登录 ssh node02 date-P 表示设置空密码省去密钥加密口令。分发完成后ssh node02 date如果能直接输出时间和日期说明免密登录生效。注意这里有个细节分发到本机这一步不能省因为有些启停脚本也会发到本机。第三步关防火墙和检查 JDK。CentOS 7 上防火墙默认开会静默拒绝 NameNode 和 DataNode 之间的 RPC 端口表现是进程活着但集群连不上。systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/config java -version关闭 SELinux 的命令有两种setenforce 0是临时生效改/etc/selinux/config是永久关。JDK 方面 Hadoop 3.x 需要 Java 8 以上java -version能正常输出版本号即可不用额外配置JAVA_HOME因为 Hadoop 的脚本会自动探测但如果你用的是自定义路径的 JDK还是建议在hadoop-env.sh里显式写JAVA_HOME这是比较稳妥的做法。另外一个常见做法是用容器环境来省去这些网络排查拉一个 Hadoop 的 Docker 镜像把 NameNode 和 DataNode 放到同一个自定义网络里配合端口映射做伪分布式实验。这种方式的好处是环境可重建但要注意容器重启后容器 IP 会变对于学习场景影响不大生产环境则不建议用容器跑 Hadoop数据本地性和磁盘冗余都会打折。3. 四个核心配置文件详解core-site、hdfs-site、mapred-site、yarn-site3.1 core-site.xml决定默认文件系统和代理用户集群运行的第一步是写core-site.xml这个文件控制的是整个集群的默认文件系统地址和临时目录等全局参数。文件位置在$HADOOP_HOME/etc/hadoop/core-site.xml下面是一份完全分布式常用的最小配置。!-- core-site.xml 核心配置 -- configuration property namefs.defaultFS/name valuehdfs://node01:8020/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property property namehadoop.proxyuser.root.hosts/name value*/value /property property namehadoop.proxyuser.root.groups/name value*/value /property /configurationfs.defaultFS是集群的门面所有客户端提交作业时默认连接这个地址8020是 NameNode RPC 的默认端口如果你改过dfs.namenode.rpc-address这里要同步改。hadoop.tmp.dir是 Hadoop 存放临时文件的根目录默认在/tmp下系统重启会被清空导致元数据丢失所以生产环境必须把它指到独立磁盘目录。这里用/data/hadoop/tmp对应的目录要提前建好并授权。proxyuser 配置是因为 Web UI 和部分客户端工具需要以代理用户身份访问不配置的话在页面提交作业时会报Failed to connect to the FileSystem。参数调整上如果你在伪分布式环境fs.defaultFS里的主机名写localhost即可端口不用变。完全分布式中这个配置在所有节点上必须一致否则 DataNode 会尝试连接不同的 NameNode表现出来是集群节点之间各说各话。3.2 hdfs-site.xml副本数、NameNode 目录和 DataNode 目录这个文件是集群运行中容错设计最关键的一处它决定了 HDFS 的元数据存哪里、数据块副本有多少个、DataNode 的数据块写到哪里。用 Hadoop 3.x 时配置如下。!-- hdfs-site.xml 核心配置 -- configuration property namedfs.namenode.name.dir/name valuefile:///data/hadoop/namenode/value /property property namedfs.datanode.data.dir/name valuefile:///data/hadoop/datanode/value /property property namedfs.replication/name value3/value /property property namedfs.namenode.secondary.http-address/name valuenode01:9868/value /property property namedfs.namenode.http-address/name valuenode01:9870/value /property /configurationdfs.namenode.name.dir是 NameNode 元数据目录格式化后会生成current/子目录存放 fsimage 和 edits 文件这个目录可以写多个路径用逗号分隔Hadoop 会同步写到每一份做冗余。这里只写一个是因为单机路径演示足够生产上至少写两个不同磁盘或挂载点。dfs.datanode.data.dir是数据块目录多块磁盘时写多个路径Hadoop 会按块大小分配不会像 RAID 那样做条带化所以这里填多路径等于手动做数据均衡。dfs.replication决定了每个块的副本数三节点集群填 3 是对的伪分布式只有一台机器时填 1否则磁盘会被重复写满这是新手最容易踩的配置坑。NameNode 的 Web 管理端口在 Hadoop 2.x 是 50070到了 Hadoop 3.x 改为 9870如果打不开页面先确认版本再排查端口。SecondaryNameNode 的 HTTP 端口在 3.x 是 9868它负责定期合并元数据镜像不配置的话默认在 localhost跨节点访问会失败。3.3 mapred-site.xml 和 yarn-site.xml计算框架和资源调度参数MapReduce 作业的运行离不开 YARNmapred-site.xml指定作业提交框架yarn-site.xml指定资源管理器地址和节点管理器资源参数。这两个文件配合不好常见的故障是作业提交成功但 Container 反复被杀内存参数冲突。!-- mapred-site.xml 核心配置 -- configuration property namemapreduce.framework.name/name valueyarn/value /property property namemapreduce.jobhistory.address/name valuenode01:10020/value /property property namemapreduce.jobhistory.webapp.address/name valuenode01:19888/value /property /configuration!-- yarn-site.xml 核心配置 -- configuration property nameyarn.resourcemanager.hostname/name valuenode01/value /property property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.nodemanager.resource.memory-mb/name value4096/value /property property nameyarn.scheduler.maximum-allocation-mb/name value4096/value /property /configurationmapreduce.framework.name必须等于yarn这是集群模式下作业走 YARN 调度的开关写错为 local 则作业只在提交节点本地跑完全失去分布式效果。yarn.resourcemanager.hostname指定 ResourceManager 所在节点其他 NodeManager 启动时靠它注册。yarn.nodemanager.aux-services配置为mapreduce_shuffle这是 MapReduce 计算框架在 NodeManager 上需要的辅助服务漏掉这项会出现作业一直卡在 ACCEPTED 状态。内存参数是调优的重点。yarn.nodemanager.resource.memory-mb是每个节点可供 YARN 使用的物理内存总量建议设为本机物理内存的 60-80%剩余留给系统进程和 DataNode。yarn.scheduler.maximum-allocation-mb是单个 Container 能申请的最大内存这两个值和mapreduce.map.memory.mb、mapreduce.reduce.memory.mb要联动调如果 Container 请求的内存超过了 maximum-allocation应用直接被拒绝如果请求值小于实际运行需要又会被 NodeManager 视为资源超标而杀掉。后面避坑章的 Container 被杀问题多半是这几组参数互相打架。4. 集群启动与日常运行格式化、启停命令和跑作业前必做的验证4.1 格式化 NameNode 和首次启动的正确顺序配置写完之后很多人直接执行start-dfs.sh结果 NameNode 起不来。原因只有一个NameNode 在第一次启动前必须格式化元数据目录格式化会生成一个集群唯一的clusterID后续 DataNode 启动时要和这个 ID 保持一致。正确顺序是先在 NameNode 所在节点执行格式化再统一启动。# 在 node01 上执行 hdfs namenode -format # 看到 Storage directory ... has been successfully formatted 则成功格式化成功后检查/data/hadoop/namenode/current/VERSION文件里面有一个clusterIDCID-xxxx的字段这就是集群的身份标识。三步里面比较隐蔽的坑是不要在 DataNode 节点上也执行格式化这样会生成另一个 clusterID导致 DataNode 连不上 NameNode。还有一点格式化命令执行两次没问题但每次都会生成新 ID旧 DataNode 上的数据块目录还留着旧 ID就会报 Incompatible clusterIDs后面避坑章会专门讲这个现象。格式化完成后执行集群启动# 在 node01 上启动 HDFS 和 YARN start-dfs.sh start-yarn.sh如果只在一台机器上手动启动全部进程也可以逐进程来先启动 NameNode 再启动 DataNodehdfs --daemon start namenode hdfs --daemon start datanode yarn --daemon start resourcemanager yarn --daemon start nodemanager mapred --daemon start historyserver脚本方式和 daemon 方式的区别在于脚本方式会按配置自动把所有节点的进程拉起适合完全分布式初次启动daemon 方式更适合排错场景某一台节点起不来时单独拉进程看日志。启动后节点的日志在$HADOOP_HOME/logs/下排查问题时先看这个目录里的.log文件而不是去网上搜报错日志行首的时间戳和 ERROR 级别字段能快速定位是哪个组件在报错。4.2 用 jps 和 Web UI 验证集群真正在运行启动命令执行完不等同于集群运行正常必须做两步验证。第一步是用jps看进程第二步是从 Web UI 看存活节点数。# 在 node01 上执行 jps # 应该看到 NameNode、SecondaryNameNode、ResourceManager # 在 node02 和 node03 上执行 jps # 应该看到 DataNode、NodeManager这里补充一个小知识点jps只显示 Java 进程如果少了 DataNode先确认 node02 和 node03 的hdfs-site.xml里dfs.datanode.data.dir目录存在且属主正确。属性不对时 DataNode 进程会启动但立即退出日志里报Permission denied。除了 jps还要跑一次 HDFS 文件系统检查命令确认数据节点真的向 NameNode 做了心跳注册hdfs dfsadmin -report # 输出内容里 Configured Capacity 和 Live datanodes (3) 两项要重点看Live datanodes的数量等于实际存活的 DataNode 数量如果显示 2 或更少说明某个节点没注册成功继续查它的日志。另外打开浏览器访问http://node01:9870进入 DataNodes 页面里面能看到每个节点的容量和使用率这是判断集群是否均衡运行的直观入口。YARN 的资源管理页面在http://node01:8088能看到 NodeManager 列表和正在运行的 Application。4.3 集群日常运行的高频操作distcp 数据迁移和 DFSIO 压测集群运行不只是启停服务更重要的是日常的数据操作。数据迁移最常见的场景是新老集群切换或者把本地大目录上传到 HDFS这时候最趁手的工具是hadoop distcp。它的全称是 Distributed Copy底层是 MapReduce 作业所以会启动 Map 任务来并行拷贝适合大数据量。# 集群内部目录拷贝 hadoop distcp -m 10 -p -update -delete hdfs://node01:8020/source/data hdfs://node01:8020/backup/data-m指定最大并发 Map 任务数设 10 表示最多 10 个 Map 并行拷贝这个值并不是越大越好因为每个 Map 都要占内存和磁盘 IO小集群超过节点核数之后会适得其反。-p保留文件属性包括权限、时间戳、块大小这些元数据生产迁移一般要带。-update做增量更新只覆盖目标目录中较旧或缺失的文件适合定期同步。-delete会删除目标目录里源目录没有的文件做镜像同步时才加谨慎使用因为删掉的文件没有后悔药。对于网络带宽有限的环境distcp 还支持限速参数-bandwidth单位是 MB/s比如-bandwidth 50表示每个 Map 任务限速 50MB/s避免迁移任务把集群带宽占满影响线上业务。跨集群拷贝时需要在两端配置对的fs.defaultFS否则 distcp 会把集群间路径误认为本地路径。另一个值得掌握的运行验证手段是 DFSIO 压测这是 Hadoop 自带的基准测试工具专门测 HDFS 的读写吞吐。用它来验证集群运行健康度很直观尤其是新集群刚搭建完跑一轮读和写测试就能发现网络或磁盘瓶颈。# 在 node01 上执行 10 个文件各 1GB 的写入测试 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 1024 # 清理测试数据注意测试默认写入 /benchmarks/TestDFSIO hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*-tests.jar TestDFSIO -clean测试结束后日志里会输出 Throughput 和 Average IO rate分别代表吞吐量和平均 IO 速度两个指标相差不大说明磁盘和网络是匹配的如果吞吐忽高忽低大概率是网络抖动或磁盘 IO 被打满。注意测试会往集群写几十 GB 数据跑完后记得-clean不然占着空间影响后续实验。5. 集群运行避坑五个高发故障的现象、原因和解决顺序5.1 DataNode 启动后连不上 NameNode活节点数一直少一个现象jps显示 DataNode 进程在但hdfs dfsadmin -report里 Live datanodes 数量少于预期NameNode 日志里刷There are N datanode(s) running and N node(s) are excluded。原因最常见的是配置不一致。DataNode 上core-site.xml的fs.defaultFS写成了本机 IP导致 DataNode 每 10 秒心跳到一个错误的 NameNode 地址其次是防火墙没有彻底关闭RPC 端口 8020 被静默拦截。解决先在所有节点上核对fs.defaultFS是否统一指向hdfs://node01:8020然后用telnet node01 8020测试网络连通性不通就重新执行防火墙关闭命令。如果是容器环境还要检查 Docker 网络的端口映射是否把 8020 暴露出来。5.2 格式化两次后旧 DataNode 报 Incompatible clusterIDs现象集群跑过一段时间后重新搭建格式化 NameNode 再启动旧 DataNodeDataNode 日志抛Incompatible clusterIDs进程退出。原因格式化会生成新的 clusterID而旧数据节点的数据目录里保存的是上一次的 clusterID。DataNode 启动时校验不匹配就直接拒绝启动。这个设计是为了防止集群被误连但也让重复格式化成为集群运行里的高发事故。解决统一处理方式是备份后清掉所有节点上的dfs.datanode.data.dir目录内容再重新格式化并启动。# 在所有 DataNode 节点上执行 rm -rf /data/hadoop/datanode/current/* # 然后回到 node01 重新格式化并启动 hdfs namenode -format start-dfs.sh要注意这种清数据操作只适用于数据不重要或本来就是测试环境生产环境绝不能随便格式化会直接丢元数据正确的做法是走 NameNode 元数据恢复流程但这个流程涉及 edits 文件回放篇幅太长这里先不展开。5.3 MapReduce 作业的 Container 反复被 NodeManager 杀掉现象作业提交后能走到 RUNNING 状态但 Application Master 反复重试错误信息是Container killed by the ApplicationMaster或running beyond physical memory limits。原因YARN 的内存参数和容器实际内存不匹配。常见配置里yarn.nodemanager.resource.memory-mb设了 4096但mapreduce.map.memory.mb和mapreduce.reduce.memory.mb没有显式设置默认值 MAP 是 1024MBREDUCE 是 1024MB。当单个 Map 任务处理的数据量较大时Java 堆外内存超限NodeManager 监测到物理内存超阈值就直接杀进程。解决把调度参数和作业参数一起设好。在yarn-site.xml里把yarn.scheduler.maximum-allocation-mb和yarn.nodemanager.resource.memory-mb设成一致再在mapred-site.xml里给 Map 和 Reduce 预留内存余量property namemapreduce.map.memory.mb/name value1536/value /property property namemapreduce.reduce.memory.mb/name value2048/value /property property namemapreduce.map.java.opts/name value-Xmx1024m/value /property这里的原则是java.opts里的堆内存要比memory.mb小 512MB 左右留给堆外内存和元空间。作业参数和调度参数的联动关系是一个节点如果 4096MB 总资源可以同时跑 2 个 1536MB 的 Map 容器再多就会被挂起等待而不是直接启动理解这个关系能避免把maximum-allocation-mb调得过大导致集群资源碎片化。5.4 NameNode 启动后立刻退出日志报 Storage directory not exist现象start-dfs.sh后 jps 看不到 NameNode日志里出现Storage directory /data/hadoop/namenode does not exist。原因dfs.namenode.name.dir指向的目录没有提前创建。Hadoop 不会自动建目录目录不存在时元数据无法读写进程直接失败。解决手动创建并设置属主再重启。mkdir -p /data/hadoop/namenode mkdir -p /data/hadoop/datanode chown -R hadoop:hadoop /data/hadoop # 属主取决于你启动 Hadoop 的用户比如当前是 hadoop 用户这里有一个对应的进阶知识点如果目录存在但内容为空NameNode 也不会启动日志会提示initialization failed此时需要重新执行格式化。所以创建目录这件事必须放在格式化之前顺序反了会导致格式化报告的路径目录是空的后续启动又报新的错。5.5 集群运行一段时间后进入安全模式写文件报 Name node is in safe mode现象HDFS 突然进入Safe mode is ON客户端写文件时返回Name node is in safe mode上传和删除操作都不能做。原因安全模式是 NameNode 启动时的保护机制它会等 DataNode 上报的块达到配置阈值才退出通常持续几十秒。如果长时间不退多半是节点掉线导致副本数不达标或磁盘空间被写满后 DataNode 无法报告块信息。解决先检查 DataNode 是否全部存活hdfs dfsadmin -safemode get hdfs dfsadmin -report如果确认只是测试环境想临时退出安全模式可以强制执行hdfs dfsadmin -safemode leave但强制退出只是临时缓解根本原因仍然是数据节点不健康或副本数不足。我一般会顺手检查每个 DataNode 的磁盘可用空间df -h看使用率超过 90% 时优先清理无用数据块。跑 MapReduce 作业前把安全模式作为一种前置检查习惯会少踩很多排队超时的坑。6. 把集群运行验证做成习惯一页健康检查清单最后一章想分享一个我一直沿用的工作习惯每次启动完集群不要只跑一个jps就继续而是按一套固定的检查顺序把集群从 HDFS 和 YARN 两方面过一遍全部通过才认为集群运行正常。这比等作业跑挂再回头排查高效得多。检查顺序可以固定为三步每一步解决不同层面的问题。第一步看进程是否存在jps的输出里至少要有对应角色第二步看心跳hdfs dfsadmin -report确认所有期望的 DataNode 在线第三步看资源yarn node -list确认 NodeManager 的可用内存总和是否符合预期。三步都通过后再跑一个最小作业做端到端验证。# 快速健康检查进程 - 存活节点 - 资源 jps hdfs dfsadmin -report | grep Live datanodes yarn node -list # 跑一个最小的 MapReduce 作业做端到端验证 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar pi 4 1000pi作业是一个自带示例用蒙特卡洛方法算圆周率Map 任务数设 4抽样次数设 1000整个作业在几十秒内完成。如果它能正常输出Estimated value of Pi说明数据读写、节点通信、资源调度这条完整链路是通的这个最小作业是我在任何集群上做的第一道验证题。什么情况下你会觉得这套流程麻烦恰恰是集群刚搭好、一切正常的时候。但集群运行这种事的特性是故障往往在磁盘写满、某台机器重启、网络抖动之后才暴露这些时刻不会提前打招呼。让检查变成肌肉记忆出问题时就能在最短时间内确认故障层。多年做大数据基础设施的一个教训是几乎每一次半夜被叫起来处理集群告警事后回溯都能落到“当初如果按健康检查清单看一遍就能提前发现”的结论。所以我现在每次给集群做完变更哪怕只是改了一个内存参数也会花三分钟按清单过一遍再宣布完成。希望这组方法能让你在 Hadoop 集群运行这条路上少熬几个夜也把异常变成可预期、可处理的事希望帮到你。本文还有配套的精品资源点击获取