前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住给大家分享一下。点击跳转到网站:https://www.captainai.net/dongkelun

前言
接Zookeeper 安装配置,本文继续总结 Hadoop HA 集群安装配置。
版本
- ZooKeeper 3.9.3
- Hadoop 3.4.1 、3.1.4 (只装过这两个版本,但 3.x 应该都一样)
下载 Hadoop
下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.4.1/hadoop-3.4.1.tar.gz
解压
1 | tar -zxvf hadoop-3.4.1.tar.gz -C /usr/local/ |
配置环境变量
1 | vi /etc/profile.d/hadoop.sh |
1 | export HADOOP_HOME=/usr/local/hadoop |
1 | source /etc/profile.d/hadoop.sh |
验证Hadoop环境变量
1 | hadoop version |
配置 Hadoop
hadoop-env.sh
1 | vi /usr/local/hadoop/etc/hadoop/hadoop-env.sh |
1 | export JAVA_HOME=/usr/local/jdk |
创建日志目录
每个节点都执行:1
mkdir -p /var/log/hadoop/hdfs
start-dfs.sh & stop-dfs.sh
分别修改 start-dfs.sh 和 stop-dfs.sh1
2vi /usr/local/hadoop/sbin/start-dfs.sh
vi /usr/local/hadoop/sbin/stop-dfs.sh
1 | 在 |
start-yarn.sh & stop-yarn.sh
分别修改 start-yarn.sh 和 stop-yarn.sh1
2vi /usr/local/hadoop/sbin/start-yarn.sh
vi /usr/local/hadoop/sbin/stop-yarn.sh
1 | 在 |
core-site.xml
1 | vi /usr/local/hadoop/etc/hadoop/core-site.xml |
1 | <configuration> |
hdfs-site.xml
1 | vi /usr/local/hadoop/etc/hadoop/hdfs-site.xml |
1 | <configuration> |
mapred-site.xml
1 | vi /usr/local/hadoop/etc/hadoop/mapred-site.xml |
1 | <configuration> |
yarn-site.xml
1 | vi /usr/local/hadoop/etc/hadoop/yarn-site.xml |
1 | <configuration> |
workers
旧版本这个文件为 slaves1
vi /usr/local/hadoop/etc/hadoop/workers
1 | indata-192-168-1-1.indata.com |
复制 Hadoop 和系统环境变量到其他节点
1 | scp -r /usr/local/hadoop-3.4.1/ 192.168.1.2:/usr/local/ |
创建软链接并使环境变量生效
在其他每个节点上都创建软链接1
2
3
4ln -s /usr/local/hadoop-3.4.1 /usr/local/hadoop
source /etc/profile.d/hadoop.sh
# 如果其他节点没有创建日志目录,记得创建一下
mkdir -p /var/log/hadoop/hdfs
启动 Hadoop 集群
第一次启动集群
因为第一次启动集群涉及格式化 NameNode 、初始化 ZooKeeper 中用于 HDFS HA 的状态存储、启动第一个 Active NameNode 、从Active NameNode 复制必要的元数据(fsimage)到Standby 节点、启动第二个 Standby NameNode,所以对于启动命令有顺序要求:
(确保每一步都执行成功,再执行后面的步骤)
1. 在每台journalnode节点执行1
2
3# 启动 JournalNode 守护进程
# JournalNode 是 HDFS HA 架构中的关键组件,用于在 Active 和 Standby NameNode 之间同步编辑日志(EditLog),确保数据一致性
hdfs --daemon start journalnode
2. 在第一个 namenode 节点执行1
2
3
4
5
6
7
8
9
10# 格式化 NameNode,这会初始化 HDFS 文件系统的元数据存储目录,创建初始的文件系统结构
# 注意:只需要在集群首次部署时执行一次,重复执行会清除已有数据
hdfs namenode -format
# 初始化 ZooKeeper 中用于 HDFS HA 的状态存储
# ZKFC(ZooKeeper Failover Controller)是用于自动故障转移的组件
# 该命令会在 ZooKeeper 中创建必要的 znode 节点,用于存储 NameNode 的状态信息
hdfs zkfc -formatZK
# 启动 NameNode 守护进程
# 启动后,该 NameNode 会作为 Active NameNode 运行(在没有其他 NameNode 的情况下)
hdfs --daemon start namenode
3. 在第二个 namenode 节点执行1
2
3
4
5
6# 将第二个 NameNode 配置为 Standby 模式
# 该命令会从 Active NameNode 复制必要的元数据(fsimage)到当前节点,确保 Standby 节点与 Active 节点的数据一致性
hdfs namenode -bootstrapStandby
# 启动第二个 NameNode 守护进程
# 由于之前执行了 bootstrapStandby,这个 NameNode 会以 Standby 模式启动,等待接管 Active 角色(当 Active 节点故障时)
hdfs --daemon start namenode
4. 启动其他服务
在任意节点执行即可:1
2
3
4
5
6
7
8
9
10
11# 启动 HDFS
start-dfs.sh
# 启动 YARN
start-yarn.sh
# 停止HDFS
stop-dfs.sh
# 停止YARN
stop-yarn.sh
# 或者启动所有
start-all.sh
stop-all.sh
非第一次启动集群
第一次启动集群成功后,后面再启停集群,只需要在任意节点执行第一次启动集群的第4步即可:
1 | # 启动 HDFS |
启动 MapReduce JobHistory Server
JobHistoryServer 需要单独启动,具体作用可以参考我之前写的Yarn Application 日志总结1
mapred --daemon start historyserver
优化启动脚本
stop-dfs.sh 和 stop-all.sh 会停止 JournalNode ,因为启动 NameNode 时会去连接 JournalNode ,但是 start-dfs.sh 和 start-all.sh 的启动顺序为 NameNode 、 DataNode 、 JournalNode , JournalNode 是在 NameNode 之后启动的,所以经常会出现只有一个 NameNode 启动成功,另外一个 NameNode 因为连接不上 JournalNode 而失败的情况,可以通过修改 start-dfs.sh 中的启动顺序,将 JournalNode 的启动脚本放在 NameNode 之前, 再加上 sleep 5 :1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#---------------------------------------------------------
# quorumjournal nodes (if any)
JOURNAL_NODES=$("${HADOOP_HDFS_HOME}/bin/hdfs" getconf -journalNodes 2>&-)
if [[ "${#JOURNAL_NODES}" != 0 ]]; then
echo "Starting journal nodes [${JOURNAL_NODES}]"
hadoop_uservar_su hdfs journalnode "${HADOOP_HDFS_HOME}/bin/hdfs" \
--workers \
--config "${HADOOP_CONF_DIR}" \
--hostnames "${JOURNAL_NODES}" \
--daemon start \
journalnode
(( HADOOP_JUMBO_RETCOUNTER=HADOOP_JUMBO_RETCOUNTER + $? ))
fi
# 这里的暂停 5s 可以根据具体情况调整
sleep 5
将上面启动 JournalNode 相关的脚本移动到 namenodes 前面,再加上 sleep 5 即可 。
hadoop.tmp.dir
启动集群后,会发现 HDFS 路径上会有一个目录:/indata/disk_0/hadoop/tmp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17hadoop fs -ls -R /indata/disk_0/hadoop/tmp
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/AMRMTokenSecretManagerRoot
-rw-r--r-- 3 root supergroup 23 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/AMRMTokenSecretManagerRoot/AMRMTokenSecretManagerNode
-rw-r--r-- 3 root supergroup 2 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/EpochNode
drwxr-xr-x - root supergroup 0 2025-09-19 09:22 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/ProxyCARoot
-rw-r--r-- 3 root supergroup 772 2025-09-19 09:22 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/ProxyCARoot/caCert
-rw-r--r-- 3 root supergroup 1217 2025-09-19 09:22 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/ProxyCARoot/caPrivateKey
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/RMAppRoot
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/RMDTSecretManagerRoot
-rw-r--r-- 3 root supergroup 17 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/RMDTSecretManagerRoot/DelegationKey_1
-rw-r--r-- 3 root supergroup 17 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/RMDTSecretManagerRoot/DelegationKey_2
-rw-r--r-- 3 root supergroup 4 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/RMVersionNode
drwxr-xr-x - root supergroup 0 2025-09-19 09:21 /indata/disk_0/hadoop/tmp/yarn/system/rmstore/FSRMStateRoot/ReservationSystemRoot
/indata/disk_0/hadoop/tmp 是 hadoop.tmp.dir 对应的值,但是该配置应该对应的本地目录,而不是 HDFS 目录,最开始怀疑自己配置错误,后来搜索源码发现了原因:
- hdfs-default.xml : 该配置文件中很多配置比如 dfs.datanode.data.dir 对应的值为 file://${hadoop.tmp.dir}/dfs/data ,该配置文件中只要用到了 hadoop.tmp.dir 都加了 file:// 前缀
- yarn-default.xml :该配置文件中很多配置比如 yarn.resourcemanager.leveldb-state-store.path 和 yarn.resourcemanager.fs.state-store.uri 对应的值均为 ${hadoop.tmp.dir}/yarn/system/rmstore ,也就是都没有加 file:// 前缀
- 加了 file:// 前缀的对应本地目录,没加的对应的 HDFS 目录,不知道不一致的原因是 bug 还是啥~
问题解决
如果有遇到启动失败的情况,可以通过查看分析对应的日志解决。
清空数据脚本
有时在自己的测试环境会有修改Hadoop版本重新部署或者安装部署失败需要重新格式化的需求,这时需要先停止所有服务,然后清空所有的数据:
停止所有服务
有时可能会遇到有残留服务进程没有停止的情况,可以通过 ps 命令再确认一遍还有没有相关的 Hadoop 进程残留1
stop-all.sh
通过clush并行的在每个节点执行下面的清理命令1
2
3
4
5sudo rm -r /indata/disk_*/datanode
sudo rm -r /indata/disk_*/journalnode
sudo rm -r /indata/disk_*/namenode
sudo rm -r /indata/disk_*/nodemanager
sudo rm -r /var/log/hadoop/hdfs/*