ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Hadoop集群启停原理与故障排查实战指南

Hadoop集群启停原理与故障排查实战指南 1. 这不是“背命令”而是理解Hadoop生态的运行脉络你搜“hadoop集群启动停止命令”点开一堆博客复制粘贴几行shell就完事——结果namenode起不来、yarn ResourceManager报错、spark-shell连不上master最后卡在日志里翻到凌晨三点。我干这行十年带过三十多个Hadoop项目最常听到的抱怨不是“不会写MapReduce”而是“集群启停像拆炸弹”。为什么因为这些命令从来不是孤立存在的指令它们是整个分布式系统状态流转的开关。namenode不是“start-dfs.sh”一敲就活了它背后牵着ZooKeeper的选举、JournalNode的日志同步、DataNode的心跳注册yarn的start-yarn.sh启动的不只是ResourceManager还有NodeManager的本地资源管理器、ApplicationMaster的调度容器、甚至可能触发Spark on YARN的Driver注册流程。你看到的是五个服务namenode、datanode、yarn、spark、hive实际背后是至少十七个进程、三类配置文件core-site.xml、hdfs-site.xml、yarn-site.xml、四层依赖关系JDK→Hadoop→ZK→YARN→Spark/Hive。所以这篇不教你怎么“背命令”而是带你把每个start/stop动作拆解成一次状态诊断namenode启动时你在看什么日志datanode连不上namenode第一眼该扫哪三行错误yarn nodemanager反复退出是内存配小了还是磁盘满了spark-submit提交后卡住到底是driver没起来还是application master被yarn拒绝了hive cli连不上metastore问题在thrift server端口还是mysql连接池耗尽我会用真实生产环境的截图级操作逻辑告诉你每条命令执行前该check什么、执行中该盯什么、执行后该验什么。适合刚搭完伪分布想上真集群的运维新人也适合开发同学排查job失败时快速定位是平台层还是应用层的问题。所有命令都基于Hadoop 3.3.6 Spark 3.4.2 Hive 3.1.3的主流组合适配CentOS 7/8和Ubuntu 20.04/22.04Windows WSL2环境也单独标注注意事项。2. 启停命令背后的架构逻辑与状态机设计2.1 HDFS的双节点协同namenode与datanode不是主从而是状态协商很多人误以为namenode是“老板”datanode是“员工”start-dfs.sh就是老板发号施令。错。HDFS启动本质是一次分布式状态协商。namenode启动后进入安全模式Safe Mode此时它不接受任何写请求只做一件事等待所有datanode完成block report块报告。每个datanode启动时会扫描本地磁盘上的block文件生成一个包含所有block ID、大小、校验和的清单通过RPC发给namenode。namenode收到足够多datanode的report默认阈值是99.9%的block已汇报才自动退出安全模式。这就是为什么你常看到“namenode处于安全模式”的告警——不是namenode挂了而是datanode没报完。实操中我见过最典型的三个卡点一是datanode的dfs.datanode.data.dir路径下有残留的in_use.lock文件强制kill进程后未清理导致datanode拒绝启动二是namenode的dfs.namenode.handler.count参数太小默认10当datanode数量超50台时handler线程池打满block report排队超时三是网络MTU不一致大块report包被分片丢弃namenode收不到完整数据。所以start-dfs.sh执行后你必须立刻检查两个日志/var/log/hadoop-hdfs/hadoop-hdfs-namenode-*.log里找“Exiting safe mode”/var/log/hadoop-hdfs/hadoop-hdfs-datanode-*.log里找“Received block report”。前者没出现看后者是否在持续重试后者报“Connection refused”立刻查namenode端口9870是否监听、防火墙是否放行。2.2 YARN的两级调度ResourceManager与NodeManager的生命周期绑定yarn的启动比HDFS更复杂因为它涉及资源隔离。start-yarn.sh启动的不是单个服务而是一个资源调度闭环ResourceManagerRM作为中央调度器负责分配ContainerNodeManagerNM作为每个节点的代理负责启动/监控Container。关键点在于NM启动时会向RM注册注册成功后RM才将其纳入可用节点池而RM自身又依赖于ZooKeeper如果启用HA或本地文件系统非HA来持久化Application状态。所以当你执行start-yarn.sh后必须验证三个状态一是jps | grep ResourceManager确认进程存在二是curl -s http://rm-host:8088/ws/v1/cluster/nodes返回JSON里activeNodes数量是否等于你的NM节点数三是任意一台NM节点上执行yarn node -list看是否显示“RUNNING”。我踩过的最大坑是NM的yarn.nodemanager.resource.memory-mb参数设为8192MB但物理内存只有12GBLinux OOM Killer直接干掉NM进程日志里只有一行“Killed process”根本找不到yarn相关错误。解决方案不是调大内存参数而是用free -h确认可用内存再按70%原则设置即12GB * 0.7 ≈ 8GB并开启yarn.nodemanager.vmem-check-enabledfalse绕过虚拟内存检查——这是生产环境标配不是偷懒。2.3 Spark的三种部署模式standalone、yarn、k8s启停逻辑天差地别Spark本身不提供集群管理它依赖外部资源管理器。所以“spark启动命令”必须先明确模式Standalone模式Spark自带Master/Worker进程start-all.sh启动Master端口8080和Worker端口8081但Worker必须能SSH免密登录到所有节点否则启动失败。实测发现CentOS 7默认禁用root SSH需改/etc/ssh/sshd_config的PermitRootLogin yes并重启sshd。YARN模式Spark不启动任何守护进程spark-submit提交任务时由YARN动态分配Container运行Driver和Executor。所谓“启动Spark”其实是确保YARN正常然后用spark-shell --master yarn测试连通性。重点检查yarn.resourcemanager.address配置是否指向正确RM地址以及spark.yarn.jars是否指向HDFS上的spark-jars目录hdfs dfs -ls /spark-jars。Kubernetes模式需要kubectl权限和spark-operator启停命令变成kubectl apply -f spark-master.yaml。但当前热词里没提k8s本文聚焦前两种。特别提醒Spark 3.x默认启用AQEAdaptive Query Execution如果yarn.scheduler.maximum-allocation-mb小于spark.sql.adaptive.enabledtrue要求的最小内存job会卡在“Waiting for resources”日志里看不到ERROR只有一堆INFO。解决方案是关掉AQE或调大yarn内存上限。2.4 Hive的元数据服务metastore不是可选组件而是单点故障核心Hive的启动最容易被误解。“hive”命令只是CLI客户端真正服务端是HiveServer2HS2和Metastore。HS2处理SQL解析和执行Metastore管理表结构、分区、统计信息等元数据。两者可合并在一个JVM--service hiveserver2也可分离部署推荐生产环境。分离时必须先启动metastorenohup hive --service metastore /var/log/hive/metastore.log 21 再启动HS2nohup hiveserver2 /var/log/hive/hiveserver2.log 21 。常见错误是metastore连不上MySQL一是jdbc url写错jdbc:mysql://mysql-host:3306/metastore?createDatabaseIfNotExisttrue少了个问号二是MySQL用户没授权GRANT ALL ON metastore.* TO hive% IDENTIFIED BY pwd; FLUSH PRIVILEGES;三是MySQL max_connections不够Hive默认连接池2010个并发查询就打满。我在线上曾因MySQL连接数爆满HS2日志循环打印“Unable to open a test connection”实际是metastore服务早挂了但HS2还在傻等。所以检查Hive永远先看metastore.log再看hiveserver2.log。3. 实操命令详解与参数精调指南3.1 HDFS启停从单节点调试到百节点集群的渐进式验证3.1.1 单节点伪分布式环境开发/测试必备# 1. 格式化namenode仅首次执行重复执行会清空所有数据 hdfs namenode -format # 2. 启动HDFS等价于 start-dfs.sh $HADOOP_HOME/sbin/hadoop-daemon.sh start namenode $HADOOP_HOME/sbin/hadoop-daemon.sh start datanode # 3. 验证三步法 # a) 进程检查 jps | grep -E NameNode|DataNode # b) 端口检查namenode默认9870datanode默认9864 netstat -tuln | grep -E :9870|:9864 # c) Web UI检查浏览器打开 # http://localhost:9870 - 查看Live Nodes数量 # http://localhost:9864 - datanode的Web UI需在datanode节点访问提示hadoop-daemon.sh是底层脚本start-dfs.sh是封装好的启动器。调试时建议用前者因为start-dfs.sh会同时启动secondarynamenode如果配置了增加干扰项。3.1.2 多节点集群启动生产环境标准流程# 1. 确保所有节点时间同步NTP是底线 ntpdate pool.ntp.org # 或配置chronyd # 2. 在namenode节点执行注意不是所有节点都执行 $HADOOP_HOME/sbin/start-dfs.sh # 3. 检查顺序严格按此顺序跳过一步可能误判 # Step 1: namenode日志 tail -100f $HADOOP_HOME/logs/hadoop-*-namenode-*.log | grep -E STARTUP|Safe mode is OFF # Step 2: 任一datanode日志选负载最低的节点 tail -100f $HADOOP_HOME/logs/hadoop-*-datanode-*.log | grep -E Registered|Block report # Step 3: HDFS健康检查 hdfs dfsadmin -report | head -20 # 查看Live Nodes、Dead Nodes、Decommissioning Nodes # Step 4: 文件系统测试创建目录上传文件 hdfs dfs -mkdir -p /test/input echo hello world | hdfs dfs -put - /test/input/test.txt hdfs dfs -cat /test/input/test.txt注意start-dfs.sh会读取$HADOOP_HOME/etc/hadoop/slaves文件里面每行一个datanode主机名。务必确保该文件内容与实际节点一致且所有节点的/etc/hosts里能解析这些主机名。我遇到过slaves文件写错IP脚本尝试SSH到不存在的IP超时60秒后才报错浪费大量时间。3.1.3 安全模式强制退出应急场景当namenode卡在安全模式且确认datanode已全部上线可手动退出# 方法1等待自动退出推荐观察日志 # 方法2强制退出仅限紧急情况 hdfs dfsadmin -safemode leave # 方法3调整安全模式阈值永久方案 # 编辑 hdfs-site.xml添加 property namedfs.namenode.safemode.threshold-pct/name value0.95/value !-- 默认0.999改为0.95表示95% block汇报即退出 -- /property # 执行刷新hdfs dfsadmin -refreshNodes警告-safemode leave是危险操作如果datanode确实没报完block强行退出会导致部分block丢失后续MR job报“No live nodes contain block”。3.2 YARN启停资源调度器的精细化控制3.2.1 ResourceManager单点启动非HA模式# 1. 启动ResourceManager仅在RM节点执行 $HADOOP_HOME/sbin/yarn-daemon.sh start resourcemanager # 2. 启动NodeManager在每个worker节点执行 $HADOOP_HOME/sbin/yarn-daemon.sh start nodemanager # 3. 验证四维检查 # a) 进程jps | grep -E ResourceManager|NodeManager # b) RM端口netstat -tuln | grep :8088 # c) NM端口netstat -tuln | grep :8042 # d) Web UIhttp://rm-host:8088/cluster - 查看Active Nodes数量3.2.2 YARN HA模式启动双RM高可用# 1. 启动ZooKeeper集群前提条件 zkServer.sh start # 2. 在第一个RM节点启动自动成为Active $HADOOP_HOME/sbin/yarn-daemon.sh start resourcemanager # 3. 在第二个RM节点启动自动成为Standby $HADOOP_HOME/sbin/yarn-daemon.sh start resourcemanager # 4. 验证HA状态 yarn rmadmin -getServiceState rm1 # 返回 active yarn rmadmin -getServiceState rm2 # 返回 standby # 5. 模拟故障切换测试用 yarn rmadmin -transitionToStandby rm1 # 将rm1切为standby yarn rmadmin -transitionToActive rm2 # 将rm2切为active实操心得YARN HA依赖ZooKeeper所以yarn.resourcemanager.zk-address必须配置正确。我曾因ZK地址写成localhost:2181实际ZK在另一台机器两个RM都卡在“Connecting to ZooKeeper”日志里疯狂重试。正确写法是zk-host1:2181,zk-host2:2181,zk-host3:2181。3.2.3 NodeManager内存调优避免OOM Killer# 关键参数编辑 yarn-site.xml property nameyarn.nodemanager.resource.memory-mb/name value8192/value !-- NM可分配的最大内存单位MB -- /property property nameyarn.nodemanager.resource.cpu-vcores/name value8/value !-- NM可分配的最大vcore数 -- /property property nameyarn.nodemanager.vmem-check-enabled/name valuefalse/value !-- 关闭虚拟内存检查防OOM Killer -- /property property nameyarn.nodemanager.pmem-check-enabled/name valuefalse/value !-- 关闭物理内存检查 -- /property # 生产环境建议内存按物理内存70%计算vcore按CPU核数*0.8计算 # 例如32核64GB服务器 - memory-mb45056(64*0.7*1024), vcores25(32*0.8)3.3 Spark启停从本地模式到YARN集群的无缝切换3.3.1 Spark Standalone模式小规模集群# 1. 启动Master在master节点 $SPARK_HOME/sbin/start-master.sh # 2. 启动Worker在每个worker节点需SSH免密 $SPARK_HOME/sbin/start-slave.sh spark://master-host:7077 # 3. 验证 # Master Web UI: http://master-host:8080 - 查看Workers数量 # Worker日志: $SPARK_HOME/logs/spark-*-org.apache.spark.deploy.worker.Worker-*.out # 4. 提交测试job $SPARK_HOME/bin/spark-submit \ --master spark://master-host:7077 \ --class org.apache.spark.examples.SparkPi \ $SPARK_HOME/examples/jars/spark-examples_2.12-3.4.2.jar \ 10注意start-slave.sh的URL必须是spark://协议不能是http://。如果Worker启动后Web UI不显示检查spark-env.sh里的SPARK_MASTER_HOST是否设为master节点IP而非localhost。3.3.2 Spark on YARN模式生产主力# 1. 确保YARN已启动见3.2节 # 2. 配置Spark连接YARN编辑 spark-defaults.conf spark.master yarn spark.submit.deployMode client # 或 cluster spark.yarn.jars hdfs://namenode:9000/spark-jars/* # HDFS上的jar包路径 # 3. 上传Spark jars到HDFS一次执行 hdfs dfs -mkdir -p /spark-jars hdfs dfs -put $SPARK_HOME/jars/*.jar /spark-jars/ # 4. 提交jobclient模式driver在提交节点运行 spark-submit \ --master yarn \ --deploy-mode client \ --class org.apache.spark.examples.SparkPi \ --executor-memory 2g \ --executor-cores 2 \ $SPARK_HOME/examples/jars/spark-examples_2.12-3.4.2.jar \ 10 # 5. 查看YARN Applicationjob是否提交成功 yarn application -list | grep SPARK # 返回类似application_1699999999999_0001 SPARK RUNNING 2023-10-01 10:00:00 user实操技巧client模式便于调试driver日志在终端输出cluster模式适合生产driver在YARN Container内运行提交节点断开不影响job。但cluster模式下driver日志需用yarn logs -applicationId application_xxx查看比client模式多一步。3.4 Hive启停元数据服务的稳定性保障3.4.1 Metastore独立部署生产推荐# 1. 启动Metastore后台运行日志重定向 nohup hive --service metastore /var/log/hive/metastore.log 21 # 2. 验证Metastore检查端口和日志 netstat -tuln | grep :9083 # 默认thrift端口 tail -50f /var/log/hive/metastore.log | grep Starting DBStore # 3. 启动HiveServer2HS2 nohup hiveserver2 /var/log/hive/hiveserver2.log 21 # 4. 验证HS2 netstat -tuln | grep :10000 # 默认thrift端口 tail -50f /var/log/hive/hiveserver2.log | grep HiveServer2 started # 5. 测试连接用beeline CLI beeline -u jdbc:hive2://hs2-host:10000 -n hiveuser -p hivepass # 进入后执行show databases;注意hive --service metastore和hiveserver2命令本质是Java进程所以nohup后必须加否则会前台阻塞。如果忘记加CtrlC中断后进程其实还在要用ps aux | grep metastore杀掉。3.4.2 Hive配置关键参数避坑清单!-- hive-site.xml 必配项 -- property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://mysql-host:3306/metastore?createDatabaseIfNotExisttrueamp;useSSLfalseamp;serverTimezoneUTC/value /property property namejavax.jdo.option.ConnectionDriverName/name valuecom.mysql.cj.jdbc.Driver/value /property property namejavax.jdo.option.ConnectionUserName/name valuehive/value /property property namejavax.jdo.option.ConnectionPassword/name valuehivepassword/value /property property namehive.server2.thrift.port/name value10000/value /property property namehive.metastore.uris/name valuethrift://metastore-host:9083/value !-- HS2连接metastore的地址 -- /property常见错误useSSLfalse和serverTimezoneUTC必须加上否则MySQL 8.0连接失败在XML中要写成amp;否则配置解析失败hive.metastore.uris必须指向metastore服务地址不能写localhostHS2和metastore通常不在同一台机器。4. 故障排查实战从日志碎片到根因定位4.1 HDFS典型故障速查表现象日志关键词根因分析解决方案namenode处于安全模式Safe mode is ONdatanode未完成block report检查datanode日志是否有Block report确认网络连通性datanode无法注册到namenodeCall From dn-host to nn-host:9820 failednamenode未监听9820端口或防火墙拦截netstat -tuln | grep :9820iptables -L -nhdfs dfs -ls 报错 Connection refusedjava.net.ConnectException: Connection refusednamenode进程未启动或core-site.xml的fs.defaultFS配置错误jps | grep NameNode检查fs.defaultFShdfs://namenode-host:9000DataNode: java.io.IOException: Incompatible clusterIDsIncompatible clusterIDsdatanode的VERSION文件clusterID与namenode不匹配删除datanode的data目录重新格式化namenode实操心得HDFS日志里最有效的线索不是ERROR而是INFO级别的状态流转。比如namenode日志里连续出现BLOCK* NameSystem#addBlock: block ... added说明block写入正常如果突然停止大概率是datanode挂了。我习惯用grep -A 5 -B 5 Exception\|FATAL hadoop-hdfs-namenode-*.log抓上下文比单纯搜ERROR更准。4.2 YARN资源调度故障定位现象日志关键词根因分析解决方案yarn application -list 返回空No applications foundResourceManager未启动或yarn.resourcemanager.address配置错误jps | grep ResourceManager检查yarn.resourcemanager.addressrm-host:8032NodeManager反复退出Killed processLinux OOM Killer干掉NM进程调小yarn.nodemanager.resource.memory-mb或关闭内存检查spark-submit卡住无日志输出Client: Waiting for applicationYARN资源不足或spark.yarn.jars路径错误yarn node -list看节点状态hdfs dfs -ls /spark-jars确认jar存在ApplicationMaster启动失败AM Container exited with exitCode: -1000Container内存超限或本地磁盘空间不足yarn logs -applicationId app_xxx看AM日志检查yarn.nodemanager.local-dirs磁盘使用率排查技巧YARN的Application日志分散在多个地方。Driver日志在提交节点client模式或AM Containercluster模式Executor日志在对应NodeManager节点的$YARN_HOME/logs/userlogs目录。最快方法是yarn logs -applicationId application_xxx app.log然后grep -E ERROR\|Exception app.log。4.3 Spark on YARN作业失败诊断链Spark job失败不是单一环节问题而是YARN调度→Container启动→Executor初始化→Task执行的链条断裂。我的标准排查链YARN层yarn application -status application_xxx→ 看FinalStatus是SUCCEEDED还是FAILEDAM层yarn logs -applicationId application_xxx \| grep ApplicationMaster→ 看AM是否启动成功Executor层yarn logs -applicationId application_xxx \| grep Executor→ 看Executor是否注册Task层yarn logs -applicationId application_xxx \| grep TaskSetManager→ 看Task是否调度常见断点AM启动失败通常是spark.yarn.jars路径不存在或HDFS权限问题hdfs dfs -ls /spark-jars返回Permission deniedExecutor注册失败spark.executor.memory设得太大YARN分配Container时超限日志报Requested container exceeds memory limitsTask失败spark.sql.files.maxPartitionBytes设得太小产生海量小task拖垮调度器4.4 Hive元数据服务崩溃复原Hive故障90%出在Metastore。当beeline连不上按此顺序检查网络层telnet metastore-host 9083→ 端口不通检查metastore进程、防火墙、SELinuxMetastore层tail -100f /var/log/hive/metastore.log→ 找Exception或Connection refusedMySQL层mysql -uhive -phivepass -h mysql-host -e use metastore; show tables;→ 连接失败检查MySQL服务、用户权限、max_connectionsHS2层tail -100f /var/log/hive/hiveserver2.log→ 如果metastore正常但HS2报错可能是hive.metastore.uris配置错误紧急恢复如果MySQL损坏Hive元数据不可逆丢失。唯一办法是从备份恢复MySQL库。所以生产环境必须每天mysqldump -u hive -p hivepass metastore /backup/metastore_$(date %F).sql并验证备份可还原。5. 高级运维技巧自动化启停与健康巡检5.1 一键启停脚本适配多节点集群#!/bin/bash # cluster-control.sh # Usage: ./cluster-control.sh {start|stop} {hdfs|yarn|spark|hive} SERVICE$2 ACTION$1 case $SERVICE in hdfs) if [ $ACTION start ]; then echo Starting HDFS... $HADOOP_HOME/sbin/start-dfs.sh sleep 10 hdfs dfsadmin -report | head -10 else echo Stopping HDFS... $HADOOP_HOME/sbin/stop-dfs.sh fi ;; yarn) if [ $ACTION start ]; then echo Starting YARN... $HADOOP_HOME/sbin/start-yarn.sh sleep 10 yarn node -list else echo Stopping YARN... $HADOOP_HOME/sbin/stop-yarn.sh fi ;; hive) if [ $ACTION start ]; then echo Starting Hive Metastore... nohup hive --service metastore /var/log/hive/metastore.log 21 sleep 5 echo Starting HiveServer2... nohup hiveserver2 /var/log/hive/hiveserver2.log 21 else echo Stopping Hive... ps aux | grep metastore | grep -v grep | awk {print $2} | xargs kill -9 ps aux | grep hiveserver2 | grep -v grep | awk {print $2} | xargs kill -9 fi ;; esac使用方式./cluster-control.sh start hdfs启动HDFS./cluster-control.sh stop hive停止Hive。脚本加入sleep和状态检查避免启停不同步。5.2 集群健康巡检脚本每日自动执行#!/bin/bash # health-check.sh # 检查HDFS/YARN/Spark/Hive核心指标 echo HDFS Health Check hdfs dfsadmin -report | grep -E Live Nodes|Dead Nodes|Decommissioning Nodes hdfs fsck / -files -blocks -locations 2/dev/null | head -10 echo YARN Health Check yarn node -list | grep -E Total Nodes|RUNNING yarn application -list -appStates RUNNING | wc -l echo Spark on YARN Check if yarn application -list 2/dev/null | grep -q SPARK; then echo Spark jobs running else echo No Spark jobs running fi echo Hive Metastore Check nc -z metastore-host 9083 echo Metastore OK || echo Metastore DOWN echo HiveServer2 Check nc -z hs2-host 10000 echo HS2 OK || echo HS2 DOWN部署crontab -e添加0 2 * * * /path/to/health-check.sh /var/log/cluster-health.log 21每天凌晨2点执行。5.3 生产环境启停黄金法则启停顺序不可逆启动按HDFS→YARN→Hive→Spark停止按Spark→Hive→YARN→HDFS。原因Spark依赖YARNYARN依赖HDFSHive依赖HDFS和MySQL。反序启停会导致服务等待超时。滚动重启策略百节点集群不要stop-all.sh而是逐台重启NodeManager先yarn-daemon.sh stop nodemanager等该节点所有Container结束再start。避免瞬间资源缺口。配置版本管理所有core-site.xml等配置文件用Git管理每次修改提交commit并在注释里写明变更原因如“2023-10-01 调整dfs.blocksize为256MB适配大文件场景”。日志保留策略Hadoop日志默认只存最近10个生产环境改$HADOOP_HOME/etc/hadoop/log4j.propertieshadoop.root.loggerINFO,RFAlog4j.appender.RFA.MaxBackupIndex30保留30天日志。我在某金融客户现场曾因未遵守启停顺序先停了HDFS再停YARN导致YARN的Application状态丢失所有正在运行的Spark job被强制kill业务方投诉。后来我们把启停流程固化成Ansible Playbook每次执行前自动校验依赖状态再也没出过问题。技术细节决定成败而流程规范保障稳定。
返回列表