上篇把 JDK、Hadoop 3 的下载解压、环境变量这些前置工作都处理完了,这篇接着往下走:改配置、格式化 NameNode、启动 HDFS 和 YARN、跑通第一个 MapReduce 任务。我在 CentOS 7 上装 Hadoop 3 的次数自己都记不清了,这篇文章就把最关键的配置逻辑和踩过的坑直接给你捋干净。
这篇默认你的环境已经具备这些条件:一台干净的 CentOS 7 虚拟机,装好了 JDK 8 或 11,Hadoop 3.3.x 已经解压到 /usr/local/hadoop,并且 JAVA_HOME、HADOOP_HOME 等环境变量已经写进了 /etc/profile。如果还没到这一步,先回去把上篇弄完再往下看,否则后面报错你会分不清是配置问题还是环境问题。
1. 动手前先做两件不起眼的小事
1.1 确认 JDK 和 Hadoop 版本真的匹配
Hadoop 3.x 官方要求 Java 8 或者 Java 11,这两个大版本都能用。但是 CentOS 7 上如果你是用 yum 装的 java-1.8.0-openjdk,要注意实际路径通常带版本号,比如 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx,而 /usr/lib/jvm/java-1.8.0-openjdk 这个路径是否真实存在,取决于你有没有装 java-1.8.0-openjdk-devel。很多教程会写死一个版本号路径,你直接抄过来,结果目录对不上,启动时就报 JAVA_HOME 相关错误。
检查的最好方式就是执行两行命令:
bash复制java -version
/usr/local/hadoop/bin/hadoop version
如果 hadoop version 能正常打印出 Hadoop 3.3.x 的版本信息,说明环境变量和 JDK 至少没大问题。如果 hadoop 命令直接提示找不到 JAVA_HOME,那就先别急着改配置文件,大概率是 /etc/profile 里的 export JAVA_HOME 路径写错了,或者你没有 source /etc/profile 让它生效。
1.2 数据目录千万别图省事放 /tmp 下
第一次装 Hadoop 的人最容易图省事,把 hadoop.tmp.dir、dfs.namenode.name.dir、dfs.datanode.data.dir 这些目录都留在默认位置。默认的 hadoop.tmp.dir 是 /tmp/hadoop-${user.name},这在生产环境就是个定时炸弹。CentOS 7 的 /tmp 目录有自动清理机制,系统重启或者临时文件被清理后,你的 NameNode 元数据可能就没了,轻则 DataNode 起不来,重则整个 HDFS 数据没法恢复。
所以动手改配置之前,先把目录结构规划好。我习惯的做法是单独建一个数据目录:
bash复制mkdir -p /data/hadoop/tmp
mkdir -p /data/hadoop/hdfs/name
mkdir -p /data/hadoop/hdfs/data
mkdir -p /data/hadoop/logs
如果你用的是 hadoop 用户而不是 root,记得把目录属主改一下,不然 Hadoop 进程没有权限写数据,启动时一样会报 Permission denied:
bash复制chown -R hadoop:hadoop /data/hadoop
这里多说一句:如果你之后打算把数据目录放在额外挂载的数据盘上,一定先确认分区挂载好了再创建目录。我有一次在云主机上没注意数据盘还没挂载,结果数据全写进了系统盘,后面扩容迁移数据时折腾了半死。提前规划好目录,后面格式化、启动、跑任务都会顺很多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 六个核心配置文件逐个拆解
Hadoop 3 的配置集中在 $HADOOP_HOME/etc/hadoop 目录下。单机伪分布式模式只需要改六个地方:hadoop-env.sh、core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml、workers。每个文件的作用不同,但经常有人把配置项放错文件,比如把 fs.defaultFS 写进 hdfs-site.xml,这种错误启动时不会马上报错,但你会发现访问 HDFS 时行为很奇怪。
2.1 hadoop-env.sh:先把 JAVA_HOME 写死
hadoop-env.sh 里要改的核心就是 JAVA_HOME。虽然你已经在 /etc/profile 里配好了 JAVA_HOME,但 Hadoop 自带的一些脚本在通过 SSH 拉起来的时候,可能不会完整继承你终端里的环境变量,所以最稳妥的办法是在 hadoop-env.sh 里直接写死。
找到文件中 JAVA_HOME 那一行,改成你自己的 JDK 路径:
bash复制export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
如果你是 root 用户装的 JDK,并且 /etc/profile 里已经配置生效,这里基本不会出问题。但我更建议在这里显式写出来,因为后续如果要把 Hadoop 配置成开机自启或者交给 systemd 托管,脚本执行环境不一定能拿到系统级环境变量。
还有一个容易被忽略的项是 HADOOP_HOME,如果 hadoop 命令本身能执行,说明 HADOOP_HOME 已经没问题了,但保险起见也可以顺手在 hadoop-env.sh 里加上,我自己的服务器上就是这么干的,省得后面写 mapreduce.application.classpath 时出现路径变量为空的诡异报错。
2.2 core-site.xml:HDFS 入口和临时目录都在这里
core-site.xml 里必须配置 fs.defaultFS,这个值决定了 Hadoop 集群的默认文件系统地址,也决定了你执行 hdfs dfs 命令时连到哪里。伪分布式模式下填 localhost:9000 就对了:
xml复制<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
</configuration>
hadoop.tmp.dir 是很多中间文件的根目录,比如 NameNode 的元数据、DataNode 的数据块默认都会基于这个目录来生成。虽然我们后面会在 hdfs-site.xml 里单独指定 name 和 data 目录,但这里把 tmp 指到 /data/hadoop/tmp 仍然很重要,可以避免系统临时目录清理导致的各种玄学问题。
fs.defaultFS 的端口 9000 是 RPC 通信端口,别和后面 Web UI 的 9870 端口搞混。很多人以为 HDFS 地址就应该是 http 的端口,结果客户端连不上就开始怀疑网络,其实 9000 走的是 RPC 协议,不是 HTTP。
2.3 hdfs-site.xml:副本数、NameNode/DataNode 目录
hdfs-site.xml 里最核心的是三个配置:副本数、NameNode 元数据目录、DataNode 数据块目录。伪分布式只有一个节点,所以副本数必须改成 1,如果保持默认的 3,DataNode 会尝试把数据复制三份,结果自己给自己复制,日志里全是副本不足的告警:
xml复制<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///data/hadoop/hdfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///data/hadoop/hdfs/data</value>
</property>
</configuration>
df s.namenode.name.dir 和 df s.datanode.data.dir 的值要带 file:// 前缀,因为 Hadoop 兼容 HDFS、S3 等多种文件系统,需要明确告诉它这里用的是本地文件系统路径。如果你不指定这两个目录,所有东西都会堆到 hadoop.tmp.dir 下,数据是能跑,但目录结构很乱,后面想备份或者迁移会很麻烦。
Hadoop 3.x 默认把 NameNode 的 Web UI 端口改成了 9870,这一点和 Hadoop 2.x 的 50070 完全不一样。如果你照着老教程配置,访问 50070 会发现端口不通,这不是防火墙的锅,是端口本身已经换了。DataNode 的 Web 端口是 9864,这个在后端排查时也能看到。
2.4 yarn-site.xml:不配这个,作业永远卡在 ACCEPTED
yarn-site.xml 是负责资源调度的,如果你只跑 HDFS 不管计算任务,这里可以先不配。但既然装了 Hadoop 3 肯定要跑 MapReduce,所以 ResourceManager 和 NodeManager 的配置必须到位。
最核心的配置是 mapreduce_shuffle 辅助服务:
xml复制<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
</configuration>
这个配置决定了 NodeManager 能不能为 MapReduce 任务提供 shuffle 服务。如果漏配了它,你的作业提交流程看起来是正常的,但会一直卡在 ACCEPTED 状态,ResourceManager 界面里能看到作业,就是死活跑不起来。
如果你的云主机内存不大,比如只有 2GB,我建议顺手把 yarn 的内存参数也调低,不然 ResourceManager 和 NodeManager 会按照物理机全部内存去申请资源,很容易把系统内存吃满导致卡死:
xml复制<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>256</value>
</property>
如果是自己学习用,关掉虚拟内存检查也可以减少很多莫名其妙的报错:
xml复制<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
2.5 mapred-site.xml:决定走 MapReduce 还是走 YARN
在 Hadoop 3 里,目录下默认没有 mapred-site.xml,只有一个 mapred-site.xml.template 模板文件。很多人第一次装的时候找不到这个文件,其实要先复制一份:
bash复制cp /usr/local/hadoop/etc/hadoop/mapred-site.xml.template /usr/local/hadoop/etc/hadoop/mapred-site.xml
然后把计算框架指定为 YARN:
xml复制<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
这一步相当于告诉 MapReduce 任务:你把计算请求提交给 YARN 去调度,而不是本地跑。初学者容易忽略 mapred-site.xml,导致明明启动了 YARN,跑作业时却只在本机跑,完全没有用到分布式集群。
在 Hadoop 3 里还有一个很常见的坑是运行示例时报 ClassNotFoundException,解决方案是在 mapred-site.xml 里手动补上 application classpath:
xml复制<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_HOME/share/hadoop/mapreduce/*:$HADOOP_HOME/share/hadoop/mapreduce/lib/*:$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/common/lib/*:$HADOOP_HOME/share/hadoop/hdfs/*:$HADOOP_HOME/share/hadoop/hdfs/lib/*:$HADOOP_HOME/share/hadoop/yarn/*:$HADOOP_HOME/share/hadoop/yarn/lib/*</value>
</property>
别问我为什么默认值还会缺类,Hadoop 3 的某些发布版本这个路径解析就是有毛病,手动配上去是最直接的解法。
2.6 workers 文件:Hadoop 3 没有 slaves 了
Hadoop 3.x 把原来 Hadoop 2.x 里的 slaves 文件改名成了 workers,含义从“从节点”变成了“工作节点”。伪分布式模式只需要在这个文件里写一个 localhost:
bash复制localhost
注意不要写多余的空行或者空格,有些版本对文件内容解析比较严格,末尾多了看不见的字符,可能启动时会把空主机名也尝试当成节点去连接,导致启动脚本卡住。
2.7 配置清单速查
经常有朋友问,到底哪些配置是必须的、哪些可以不加。我把伪分布式模式下最常见的一组配置整理成一张表:
| 配置文件 | 关键配置项 | 伪分布式推荐值 | 作用 |
|---|---|---|---|
| hadoop-env.sh | JAVA_HOME | /usr/lib/jvm/java-1.8.0-openjdk | 让 Hadoop 启动脚本能找到 JDK |
| core-site.xml | fs.defaultFS | hdfs://localhost:9000 | HDFS 默认入口地址 |
| core-site.xml | hadoop.tmp.dir | /data/hadoop/tmp | 中间文件和临时目录根路径 |
| hdfs-site.xml | dfs.replication | 1 | 副本数,单机必须为 1 |
| hdfs-site.xml | dfs.namenode.name.dir | file:///data/hadoop/hdfs/name | NameNode 元数据存储位置 |
| hdfs-site.xml | dfs.datanode.data.dir | file:///data/hadoop/hdfs/data | DataNode 数据块存储位置 |
| yarn-site.xml | yarn.nodemanager.aux-services | mapreduce_shuffle | 启用 MapReduce Shuffle 服务 |
| mapred-site.xml | mapreduce.framework.name | yarn | 让任务提交到 YARN |
| workers | 节点列表 | localhost | 声明工作节点 |
这组配置不是官方文档里最精简的,但是我在 CentOS 7 上实测过最不容易出幺蛾子的组合。你完全可以在跑通之后再逐步去掉冗余项,到时候出了问题也更好定位。
3. SSH 免密、格式化 NameNode 与启动顺序
3.1 为什么单机也要配 SSH 免密
很多教程会告诉你 start-dfs.sh 在执行时会通过 SSH 连接到每一台机器启动 DataNode,所以集群环境要配置 SSH 免密登录。但不少人以为单机伪分布式就不需要,结果执行 start-dfs.sh 的时候发现还是要输入密码,卡在那里半天不知道怎么回事。
原因很简单:Hadoop 的启动脚本即使连接 localhost 也是走 SSH 的。你要是不想每次启动都输密码,就先配置好 localhost 的免密登录。配置流程很短:
bash复制ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
然后执行 ssh localhost 试一下,如果不再提示输入密码,说明配置成功。这一步在实际多节点集群里同样适用,只是需要把每台机器的公钥都追加到目标机器的 authorized_keys 里。
如果你用的是 hadoop 用户,务必在 hadoop 用户的家目录下执行这些命令,不要图方便在 root 下生成密钥,然后切到 hadoop 用户又说免密不生效,那是密钥放错了地方。
3.2 格式化 NameNode:一次性的动作,别手滑
格式化 NameNode 是安装 Hadoop 3 过程中最关键的一步,也是最容易被反复执行的一步。执行命令:
bash复制hdfs namenode -format
先解释一下格式化到底做了什么:它会在你指定的 dfs.namenode.name.dir 目录里生成 namespace ID、block pool ID 以及初始的 fsimage 镜像文件。这些是 HDFS 的“身份证”,DataNode 启动时会拿着自己的 cluster ID 和 NameNode 的 cluster ID 做比对,不一致就拒绝注册。
很多初学者第一次启动发现 DataNode 起不来,上网一搜,老教程说要重新格式化,于是又执行了一次格式化,结果 DataNode 更起不来。原因就是格式化会重新生成 cluster ID,而 DataNode 之前已经用旧 ID 初始化了数据目录,两边对不上,DataNode 就一直报 Incompatible clusterIDs 错误。
正确做法是:格式化之前先确认数据目录是空的,或者如果已经格式化过又想重新来,把 dfs.namenode.name.dir 和 dfs.datanode.data.dir 下的 current 目录都删掉再格式化:
bash复制rm -rf /data/hadoop/hdfs/name/current
rm -rf /data/hadoop/hdfs/data/current
hdfs namenode -format
格式化过程中会提示是否确认重新格式化,输入 Y 回车。看到 successfully formatted 字样才算成功,如果只是打印一堆日志没有这句话,基本可以判断格式化没有真正完成。
3.3 启动 HDFS 和 YARN,分开启动更好排查
启动顺序其实没有严格的先后要求,但我习惯先启动 HDFS 再启动 YARN。因为先启动 YARN 而 HDFS 还没就绪时,NodeManager 注册上报时会有些干扰告警,虽然不一定影响使用,但日志里多了噪音,排查问题时不方便。
启动命令在 $HADOOP_HOME/sbin 目录下:
bash复制start-dfs.sh
start-yarn.sh
如果你只想启动 HDFS 用于文件存储,不跑 MapReduce,那 start-yarn.sh 可以暂时不执行。我平时排查问题就喜欢分开启动,这样能明确知道是 HDFS 的问题还是 YARN 的问题。
如果启动过程没有任何报错,可以再访问一下 9870 端口确认 NameNode Web UI 能打开。如果这一步失败了,优先去 logs 目录看 hadoop-xxx-namenode-xxx.log,日志比启动脚本的提示靠谱得多。
3.4 用 jps 核对最小进程集合
启动完成后,最快速的健康检查是在节点上执行 jps。如果是完整的伪分布式,你应该能看到 6 个进程:NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager、Jps。
少一个是常态,少了 NameNode,说明格式化可能有问题或者目录权限不对;少了 DataNode,优先怀疑 cluster ID 不一致;少了 ResourceManager,先查 yarn-site.xml 有没有语法错误;少了 NodeManager,检查内存配置是否超限。
这里有个很容易被忽略的点:如果你的 CentOS 7 上还跑着其他 Java 服务,jps 输出的进程会多出很多,别被干扰。你要关注的始终是 Hadoop 这几个核心进程,其他的可以先忽略。
4. 验证集群真的能干活
4.1 Web UI 是最直观的体检报告
进程都起来了,不代表集群真的能正常服务。打开浏览器访问 NameNode 的 Web UI:http://你的IP:9870,在首页能看到集群的存储容量、存活节点数、故障节点数等基本信息。如果 DataNode 状态显示 Live Nodes 数量为 1,说明 HDFS 这一层已经通了。
再访问 YARN 的 Web UI:http://你的IP:8088,这个界面主要看 ResourceManager 是否正常运行,以及后面提交的任务状态。注意如果你的虚拟机开了防火墙,CentOS 7 默认用的是 firewalld,记得放行这几个端口:
bash复制firewall-cmd --zone=public --add-port=9870/tcp --permanent
firewall-cmd --zone=public --add-port=8088/tcp --permanent
firewall-cmd --reload
如果是在本机虚拟机里访问,可以从宿主机直接访问 VM 的 IP;如果是云服务器,还得在安全组里放行端口,这是很多人装了以后打不开页面的原因。
4.2 用 HDFS 命令创建目录和上传文件
Web UI 只能说明进程活着,要确认 HDFS 的读写链路正常,还是得实际操作一下文件和目录。先创建测试目录并上传一个本地文件:
bash复制hdfs dfs -mkdir -p /test
echo "hello hadoop" > /tmp/test.txt
hdfs dfs -put /tmp/test.txt /test/
hdfs dfs -ls /test/
hdfs dfs -cat /test/test.txt
如果 put 成功而且 cat 能打印出 hello hadoop,说明 NameNode 分配数据块的流程是通的,DataNode 写入也成功了。这一步很重要,因为后面跑 MapReduce 时所有读写都建立在 HDFS 正常的基础上。如果这里就报错,先别急着跑示例,回头检查防火墙、目录权限和 DataNode 状态。
4.3 跑通第一个 WordCount
WordCount 相当于大数据圈的 Hello World。Hadoop 3 安装包自带了示例 jar,路径在 $HADOOP_HOME/share/hadoop/mapreduce 下。执行前先在 HDFS 上建一个输入目录,把刚才的 test.txt 传进去:
bash复制hdfs dfs -mkdir -p /wordcount/input
hdfs dfs -put /tmp/test.txt /wordcount/input/
然后运行自带的 WordCount 示例:
bash复制hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount /wordcount/input /wordcount/output
这里有个细节比较容易踩坑:输出目录 /wordcount/output 必须是“不存在的”。MapReduce 框架为了保证结果一致性,不允许覆盖已有输出目录。如果你第一次跑的时候输出目录已经建好或者跑失败了但残留了部分数据,第二次执行就会直接报错说输出目录已存在,需要先删掉旧目录再跑。
跑完以后查看输出:
bash复制hdfs dfs -cat /wordcount/output/part-r-00000
如果能看到单词统计结果,说明你的 HDFS、YARN、MapReduce 全链路都已经打通了。走到这一步,Hadoop 3 在 CentOS 7 上的安装基本宣告成功。
5. 几个高频问题的排查记录
5.1 每次格式化后 DataNode 就起不来
这是我在各种技术群里被问到最多的问题。启动数据节点后,jps 里刚开始能看到 DataNode,几秒后进程就没了,查看日志报 Incompatible clusterIDs。
根因就是我前面说的,NameNode 格式化生成了新的 clusterID,而 DataNode 数据目录里还是旧的 clusterID。解决办法在 3.2 里给过了,删掉 data 目录下的 current 再重新格式化,或者手动把 NameNode 和 DataNode 两边的 clusterID 改成一致。手动改 clusterID 适合已经存了重要数据、不想删的情况:去 namenode current/VERSION 里拿到 clusterID,再修改 datanode current/VERSION 里的 clusterID,然后重启 DataNode。
这个坑的启示是:格式化 NameNode 之前一定想清楚,它不是普通的重置操作,而是重新生成 HDFS 身份信息。
5.2 JAVA_HOME is not set 这个报错
启动脚本报这个错时,你第一反应可能是自己没配环境变量,可你 echo $JAVA_HOME 明明有值。问题往往出在 hadoop-env.sh 里没有写死 JAVA_HOME,而 Hadoop 脚本在某个子进程环境里拿不到系统级的 JAVA_HOME。
不要跟它较劲,直接在 hadoop-env.sh 里 export 一份显式的 JAVA_HOME 路径,问题立刻消失。这个过程就像你明明把家里钥匙放门口垫子下了,但半夜回家的人不知道,那就直接在门框上贴一张纸条告诉他在哪,别让每个人来了都翻一遍垫子。
5.3 Web UI 打不开,但 jps 进程都正常
jps 正常只能说明 Java 进程活着,Web UI 打不开多半是网络层的问题。CentOS 7 默认 firewalld 是开启的,你得先确认进程在监听哪些端口:
bash复制netstat -tlnp | grep java
如果看到 9870 和 8088 在监听,那就是防火墙把端口挡了,使用我前面给的 firewall-cmd 命令放行端口。如果是在云服务器上,还要检查安全组规则。本地虚拟机的话,确认 VM 网络模式是不是 NAT,NAT 模式下宿主机访问 VM 一般没问题,但外部机器访问不了,这属于网络模式限制,不是 Hadoop 的锅。
5.4 作业一直停在 ACCEPTED,怎么等都跑不动
ResourceManager 界面能看到任务,状态却一直是 ACCEPTED,这基本就是 yarn-site.xml 里没有配置 mapreduce_shuffle 辅助服务。MapReduce 任务在 shuffle 阶段需要 NodeManager 辅助处理数据,没这个服务,任务就一直卡着等资源。
另外一个小内存机器常见的情况是,你给 NodeManager 分配的内存不够,但 MapReduce 申请的内存超过了上限,任务会被无限挂起。可以像我前面那样调低 yarn.scheduler 相关的内存参数,或者直接关掉虚拟内存检查,让任务先跑起来再说。
5.5 常见问题排查速查表
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| DataNode 启动后马上退出 | NameNode 与 DataNode clusterID 不一致 | 查看 data 目录 current/VERSION 的 clusterID |
| 启动脚本提示输入密码 | SSH 免密未配置或密钥权限不对 | 执行 ssh localhost 测试免密 |
| 上传文件报权限不足 | 数据目录属主不是运行用户 | chown -R 到 hadoop 用户 |
| NameNode Web UI 端口不通 | Hadoop 3 默认 9870,不是老版本 50070 | netstat 确认监听端口 |
| 作业状态一直 ACCEPTED | 缺少 mapreduce_shuffle 或资源不足 | 查看 yarn-site.xml 配置 |
| ClassNotFoundException | Hadoop 3 classpath 解析异常 | 在 mapred-site.xml 手动设置 application.classpath |
| 启动脚本卡住很久 | workers 文件有脏数据或主机名解析失败 | 检查 hosts 映射,清理 workers 文件 |
6. 从伪分布式扩展到真集群时,你要改的是这几点
如果在虚拟机上把伪分布式跑通了,下一步想扩展成真正的多节点集群,其实并不复杂,核心就是把之前写死的 localhost 改成真实主机名,并保证节点之间网络互通、免密登录成功。
需要调整的地方主要有三个:core-site.xml 中 fs.defaultFS 的 localhost 改成 NameNode 所在机器的主机名;workers 文件里改成所有 DataNode 的主机名列表;所有配好改环境,包括 JDK、目录权限,然后用相同步骤初始化其他节点。
常见的一个误区是照搬伪分布里的副本数 1,真实集群想保证数据可靠性,至少要改成 2 或 3。如果数据节点数量不够,副本数设置得比节点数还多,虽然没有致命问题,但一直会有副本不足的告警,看着很闹心。
启动顺序上,先在所有节点上确保 SSH 免密都能互相连通,然后在 NameNode 节点上执行 start-dfs.sh 和 start-yarn.sh,脚本会自动去 workers 列表里的机器上拉起对应进程。如果你在 NodeManager 节点上手动一个一个启动也不是不行,但不推荐,手动启动容易出现进程归属用户不一致、环境变量没加载等奇怪问题。
多节点集群的数据目录、用户、JDK 路径尽量保持和 NameNode 一致,这点非常重要。Hadoop 不像别的服务可以通过配置中心下发差异配置,它的很多脚本是直接从本机读取本地路径的,路径不一致会导致启动脚本在部分节点上报错。
我自己的经验是:在伪分布阶段把配置和启动流程彻底跑通一次,再上多节点心里才有底。很多人一上来就照着多节点教程配了三台机器,结果有问题都不知道是该查 NameNode 还是 DataNode,其实在单机上先把集群运行的原理摸清楚,后面扩展就是改几个文件的事。
如果你在这篇的操作里还是遇到了报错,优先去看 $HADOOP_HOME/logs 下的日志文件,用户名和进程名都拼在日志文件名里,比如 hadoop-hadoop-namenode-centos7.log,找到对应日志再去搜错误关键词,基本都能定位到问题。我自己排查 Hadoop 问题时,80% 的时间都花在翻日志上,配置文件反而不容易出错。
