Hadoop 3.3.6 从单节点到三节点集群部署全复盘:踩坑实录与NFS共享方案
一、实操背景与整体说明
这次实操从头到尾把 Hadoop 3.3.6 从单节点伪分布式,一步步扩容到三节点完全分布式集群,中间踩了好几个经典的入门坑------主机名解析失败、jps 命令找不到、NFS 权限不对、集群 ID 不一致等等。全程采用 NFS 共享 /home/hadoop 目录的方式同步安装包与配置文件,省了大量重复拷贝的功夫。这里把完整流程和踩坑排错的过程都记录下来,既方便自己复盘,也给刚入门的同学避避坑。
二、环境准备与基础资源
2.1 节点规划
本次实验共 4 台 CentOS 7 服务器,角色划分如下:
- server1:主节点,运行 NameNode、SecondaryNameNode、ResourceManager
- server2 / server3 / server4:从节点,运行 DataNode、NodeManager
- 基础安装包:
jdk-8u181-linux-x64.tar.gz、hadoop-3.3.6.tar.gz
2.2 运行用户与安装包准备
我先在 server1 上创建了专门的 hadoop 用户,统一设置密码为 123456,方便实验环境操作,再把两个安装包移动到 hadoop 用户的家目录下。
# 创建hadoop用户并设置密码
useradd hadoop
echo "123456" | passwd --stdin hadoop
# 移动安装包到hadoop家目录
mv /root/hadoop-3.3.6.tar.gz /root/jdk-8u181-linux-x64.tar.gz /home/hadoop/
切换到 hadoop 用户,解压两个安装包并重命名为短名称,方便后续配置。
su - hadoop
tar zxf jdk-8u181-linux-x64.tar.gz
mv jdk1.8.0_181 jdk
tar zxf hadoop-3.3.6.tar.gz
mv hadoop-3.3.6 hadoop

2.3 配置 JAVA_HOME 环境变量
Hadoop 运行依赖 Java 环境,需要先在 hadoop-env.sh 中显式指定 JDK 路径,否则启动时会找不到 Java。
cd /home/hadoop/hadoop/etc/hadoop
# 在hadoop-env.sh中添加配置
export JAVA_HOME=/home/hadoop/jdk

配置完成后验证 hadoop 命令是否能正常调用,能正常输出命令帮助说明基础环境没问题。

三、单节点伪分布式部署实施
3.1 SSH 免密登录配置
Hadoop 集群启动需要节点间通过 SSH 免密通信,哪怕是单节点也要配置 localhost 免密。我直接生成 RSA 密钥对,把公钥追加到授权密钥文件里,再修改权限。
# 生成密钥对,空密码
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
# 公钥写入授权文件
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 授权文件必须是600权限,否则SSH会拒绝
chmod 600 ~/.ssh/authorized_keys
配置完成后测试 ssh localhost,第一次需要输入 yes 确认主机指纹,后面就能直接免密登录了。

3.2 核心配置文件修改
3.2.1 core-site.xml 核心配置
指定 HDFS 默认访问地址和端口,这里主节点主机名用 server1,端口 9000。
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://server1:9000</value>
</property>
</configuration>

3.2.2 hdfs-site.xml 副本配置
单节点环境下副本数设为 1 即可,避免多余的副本冗余。
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>

3.2.3 workers 从节点列表
单节点伪分布式直接写 localhost 就行。
3.3 NameNode 格式化与主机名解析踩坑
本来以为配置完直接格式化就能启动,结果一执行命令就抛了 java.net.UnknownHostException: bogon 的错。我第一反应是主机名解析有问题------系统主机名是 bogon,但 /etc/hosts 里根本没配对应的映射,Hadoop 启动时找不到自己的主机名,自然就报错了。
cd /home/hadoop/hadoop
bin/hdfs namenode -format

解决起来也简单,切到 root 用户,把 server1 和对应的 IP 加到 /etc/hosts 里,ping 一下通了就没问题了。
vim /etc/hosts
# 添加映射:192.168.241.171 server1
ping server1 -c 2

3.4 启动 HDFS 与环境变量踩坑
修复主机名后重启 HDFS,进程能正常拉起,我想用 jps 查看进程,结果直接提示 command not found。这才想起来,还没把 JDK 和 Hadoop 的命令路径加到系统环境变量里,自然找不到命令。
sbin/stop-dfs.sh
sbin/start-dfs.sh
jps

我编辑 hadoop 用户的 ~/.bash_profile,把 JAVA_HOME、HADOOP_HOME 都配置好,把 bin 和 sbin 目录都加入 PATH。
export JAVA_HOME=/home/hadoop/jdk
export HADOOP_HOME=/home/hadoop/hadoop
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

source 生效后再执行 jps,NameNode、DataNode、SecondaryNameNode 三个核心进程都正常运行,单节点 HDFS 终于部署完成。

四、单节点功能验证
4.1 HDFS 基础操作测试
先在 HDFS 上创建用户目录,这是后续运行 MapReduce 的前提,然后用 ls 命令验证目录创建成功。
hdfs dfs -mkdir /user
hdfs dfs -mkdir /user/hadoop
hdfs dfs -ls /user

打开浏览器访问 http://192.168.241.171:9870,在 WebUI 的文件浏览页面也能看到刚创建的目录,可视化确认正常。

4.2 YARN 部署与配置校验
先通过 hadoop conftest 命令批量校验所有配置文件的语法合法性,确保没有 XML 格式错误,再启动 YARN 集群。
# 校验所有配置文件
hadoop conftest -conf etc/hadoop/yarn-site.xml
# 启动YARN
sbin/start-yarn.sh
启动完成后 jps 查看,ResourceManager 和 NodeManager 进程都正常运行,YARN 资源调度框架部署成功。

4.3 MapReduce WordCount 功能测试
最经典的单词统计示例必须跑一遍,验证整套计算框架是否通畅。我先在本地创建测试文件,写入测试单词,再上传到 HDFS,最后提交官方示例 Jar 包运行任务。
# 准备本地测试文件
mkdir -p ~/input
echo "hello hadoop hello world hello bigdata" > ~/input/test.txt
echo "hadoop yarn hdfs mapreduce hadoop" >> ~/input/test.txt
# 上传到HDFS
hdfs dfs -put ~/input /user/hadoop/input
# 提交wordcount任务
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /user/hadoop/input /user/hadoop/output

任务运行完成后查看输出文件,每个单词的出现次数都统计正确,说明单节点的 HDFS+YARN+MapReduce 整套环境完全跑通了。

再去 WebUI 总览页面确认集群状态,版本、容量、块数量都和预期一致,单节点部署圆满收官。

五、多节点集群扩容:基于NFS共享目录方案
单节点跑通之后,开始扩容多节点。这次我用了 NFS 网络文件共享的方案------把 server1 上的 /home/hadoop 目录共享出去,其他从节点直接挂载。这样安装包、配置文件、密钥都只需要维护一份,改一次所有节点同步生效,非常适合实验环境快速搭建集群。
5.1 NFS 服务端配置(server1)
先在服务端安装 nfs-utils 工具包。
yum install -y nfs-utils

然后编辑 /etc/exports 配置共享规则,这里要特别注意 anonuid 和 anongid 必须和 hadoop 用户的 UID/GID 一致,否则挂载后文件属主会变成 nfsnobody,导致 hadoop 用户没有读写权限。
/home/hadoop *(rw,sync,anonuid=1000,anongid=1000)
配置完成后启动 NFS 服务并设置开机自启,用 showmount 命令验证共享目录是否正常导出。
systemctl enable --now nfs-server
showmount -e localhost

5.2 NFS 客户端配置(server2 / server3)
先在 server2 上操作,第一步同样安装 nfs-utils。安装完成后执行 showmount -e server1 直接报错 Unknown host,又是熟悉的主机名解析问题,马上修改 /etc/hosts 添加 server1 的 IP 映射,ping 通之后就正常了。

接下来尝试挂载 NFS 目录,提示挂载点不存在。先创建 /home/hadoop 目录,再创建 hadoop 用户,修改目录属主为 hadoop,最后执行挂载,用 df -h 确认挂载成功。
# 创建挂载点
mkdir -p /home/hadoop
# 创建hadoop用户
useradd hadoop
echo "123456" | passwd --stdin hadoop
# 修改目录属主
chown hadoop:hadoop /home/hadoop
# 挂载NFS共享目录
mount server1:/home/hadoop /home/hadoop
# 验证挂载
df -h | grep home/hadoop

server3 执行和 server2 完全相同的操作,这里就不重复赘述了。
5.3 节点间 SSH 免密配置
Hadoop 启动时需要主节点能免密登录所有从节点,因为我们用了 NFS 共享家目录,server1 上 hadoop 用户的公钥已经同步到所有节点了,直接测试免密登录即可。
ssh server2 echo "server2免密登录成功"
ssh server3 echo "server3免密登录成功"
两台机器都能免密登录,集群通信的基础就通了。

5.4 集群配置修改与重启
5.4.1 调整副本数与从节点列表
现在有两个从节点了,把 HDFS 副本数调整为 2,保证数据可靠性。
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>

然后修改 workers 文件,把原来的 localhost 替换成 server2、server3 两个从节点的主机名。
5.4.2 重启集群并重新格式化
先停止所有 HDFS 和 YARN 服务,删除旧的临时数据目录,然后重新格式化 NameNode。这里一定要注意:重新格式化前必须清空旧数据,否则会导致集群 ID 不一致,DataNode 无法注册到 NameNode。
# 停止所有服务
sbin/stop-dfs.sh
sbin/stop-yarn.sh
# 删除旧数据目录
rm -rf /tmp/hadoop-hadoop
# 重新格式化NameNode
bin/hdfs namenode -format

格式化完成后启动集群,分别登录 server2 和 server3 查看 jps,DataNode 进程都正常启动。


回到 WebUI 的 DataNode 列表页面,两个节点都在线且状态正常,双节点分布式集群扩容成功。

5.5 再扩容:新增 server4 节点
尝到 NFS 共享的甜头,我决定再扩容 server4 节点,流程和之前完全一致:配置 hosts、创建 hadoop 用户、安装 nfs-utils、挂载共享目录。


这里踩了个小坑:一开始我用 root 用户去配置 SSH 免密,还搞错了密钥路径,一直报错。后来才反应过来,Hadoop 集群的免密是针对 hadoop 用户的,切到 hadoop 用户后,因为 NFS 已经同步了 .ssh 目录,免密直接就通了。然后手动启动 DataNode 进程即可。
su - hadoop
cd /home/hadoop/hadoop
bin/hdfs --daemon start datanode


在主节点执行 hdfs dfsadmin -report 查看节点状态,Live datanodes 变成了 3 个。

WebUI 上也能看到三个 DataNode 全部在线,三节点 HDFS 集群正式搭建完成。

六、踩坑点汇总与实操总结
6.1 核心踩坑点汇总
- NameNode 格式化报 UnknownHostException
- 报错现象:格式化时提示
bogon: Name or service not known - 排查思路:系统主机名未在 hosts 文件中映射,Hadoop 无法解析本机地址
- 解决方法:在
/etc/hosts中添加 IP 与主机名的对应关系
- 报错现象:格式化时提示
- jps 命令找不到
- 报错现象:
-bash: jps: command not found - 排查思路:JDK 的 bin 目录未加入系统环境变量
- 解决方法:在用户环境变量文件中配置 JAVA_HOME,并将 bin 目录加入 PATH,source 生效
- 报错现象:
- NFS 挂载后权限异常
- 报错现象:hadoop 用户无法读写挂载目录,文件属主显示为 nfsnobody
- 排查思路:NFS 匿名用户 UID 与 hadoop 用户不匹配
- 解决方法:在
/etc/exports中配置anonuid和anongid与 hadoop 用户的 UID/GID 一致
- 重新格式化后 DataNode 无法启动
- 报错现象:DataNode 进程启动后自动退出,日志提示集群 ID 不匹配
- 排查思路:旧数据目录保留了原集群 ID,与新格式化的 NameNode 不一致
- 解决方法:格式化前删除所有节点的
/tmp/hadoop-hadoop数据目录
- SSH 免密用户混淆
- 报错现象:启动集群时提示权限拒绝,需要输入密码
- 排查思路:误用 root 用户配置免密,Hadoop 实际以 hadoop 用户运行
- 解决方法:统一在 hadoop 用户下配置 SSH 免密,确保所有从节点都能免密访问
6.2 实操心得
这次从单节点到三节点的部署走下来,最大的感受是:Hadoop 的坑绝大多数都不在框架本身,而在基础环境细节上------主机名、SSH、环境变量、文件权限,这些不起眼的小地方没做好,后面肯定会出各种莫名其妙的问题。
用 NFS 共享家目录的方式扩容真的很适合实验环境,配置文件只需要维护一份,新增节点只需要挂载就能用,效率很高。但生产环境肯定不推荐这么用,NFS 会成为明显的单点故障,生产环境还是建议各节点本地部署 + 配置管理工具同步。
另外 WebUI 真的是排错神器,节点状态、块信息、容量使用一目了然,比纯命令行排查直观太多。后续还可以继续完善 SecondaryNameNode 独立部署、ResourceManager 高可用等特性,一步步把集群架构搭得更完整。