clgzyh Blog

Hadoop-3.4.2高可用集群部署

创建于 2025-11-19 | 上次更新 2025-11-19

本实验基于前文Hadoop-3.4.2集群化部署作为基础环境

将当前的 Hadoop 3.4.2 三节点标准集群(1 NameNode + 2 DataNode) 升级为 高可用(HA, High Availability)集群,核心目标是:避免单点故障(SPOF),即当主 NameNode 宕机时,备用 NameNode 能自动接管服务。

架构对比

组件 原始架构 HA 架构
NameNode 1 个(master) 2 个:active + standby(例如 master + slave1)
共享存储 QJM(Quorum Journal Manager) 或 NFS(推荐 QJM)
故障切换 手动 自动(通过 ZooKeeper + ZKFC)
ResourceManager 1 个 可选 HA(本指南先聚焦 HDFS HA)

一、新增组件与角色规划(仍用 3 节点)

主机名 IP 角色
hadoop01 (master) 10.0.0.10 NameNode (active), ZKFC, JournalNode, DataNode(可选), ResourceManager
hadoop02 (slave1) 10.0.0.20 NameNode (standby), ZKFC, JournalNode, DataNode, NodeManager
hadoop03 (slave2) 10.0.0.30 JournalNode, DataNode, NodeManager, ZooKeeper

💡 说明:

  • JournalNode:至少 3 个(奇数),用于同步 edits 日志
  • ZooKeeper:至少 3 节点(可复用现有机器)
  • ZKFC(ZooKeeper Failover Controller):运行在每个 NameNode 上,监控 NN 状态并触发切换

二、部署步骤概览

  1. 安装 ZooKeeper(3 节点)
  2. 配置 JournalNode
  3. 修改 HDFS 配置启用 HA
  4. 初始化 JournalNode 和 NameNode HA 状态
  5. 启动 HA 集群
  6. 验证故障切换

步骤 1:部署 ZooKeeper(在所有 3 节点)

1.1 下载并解压(所有节点)

# 以 hadoop 用户操作
cd ~
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin zookeeper

1.2 配置 zoo.cfg(所有节点)

mkdir -p ~/zookeeper/data
echo "1" > ~/zookeeper/data/myid   # master 上为 1
# slave1 上执行:echo "2" > ~/zookeeper/data/myid
# slave2 上执行:echo "3" > ~/zookeeper/data/myid

编辑 ~/zookeeper/conf/zoo.cfg

tickTime=2000
dataDir=/home/hadoop/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

1.3 启动 ZooKeeper(所有节点)

~/zookeeper/bin/zkServer.sh start
# 检查状态
~/zookeeper/bin/zkServer.sh status

应看到一个 leader,两个 follower

步骤 2:配置 Hadoop HA(在 master 上修改)

2.1 修改 hdfs-site.xml

vim hdfs-site.xml
<configuration>
    <!-- 启用 HA -->
    <property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>

    <!-- 定义两个 NameNode 的 ID -->
    <property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2</value>
    </property>

    <!-- nn1 (master) 的 RPC 地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>master:9000</value>
    </property>

    <!-- nn2 (slave1) 的 RPC 地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>slave1:9000</value>
    </property>

    <!-- nn1 的 HTTP 地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>master:9870</value>
    </property>

    <!-- nn2 的 HTTP 地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>slave1:9870</value>
    </property>

    <!-- JournalNode 地址(3 节点) -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value>
    </property>

    <!-- 客户端故障转移代理 -->
    <property>
        <name>dfs.client.failover.proxy.provider.mycluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <!-- 启用自动故障转移 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <!-- JournalNode 本地目录 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/home/hadoop/hadoop/journalnode</value>
    </property>

    <!-- 其他原有配置保留 -->
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/hadoop/hadoop/hdfs/namenode</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/home/hadoop/hadoop/hdfs/datanode</value>
    </property>
    
    <!-- 防护方法配置 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/hadoop/.ssh/id_rsa</value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
    </property>
</configuration>

2.2 修改 core-site.xml

vim core-site.xml
<configuration>
    <!-- 使用 nameservice 名称代替具体主机 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>

    <!-- ZooKeeper 地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>master:2181,slave1:2181,slave2:2181</value>
    </property>

    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/hadoop/tmp</value>
    </property>
</configuration>

3 分发配置到所有节点

for node in master slave1 slave2; do
  scp ~/hadoop/etc/hadoop/{core-site.xml,hdfs-site.xml} hadoop@$node:~/hadoop/etc/hadoop/
done

步骤 3:初始化 HA 状态

3.1 启动 JournalNode(所有节点)

hdfs --daemon start journalnode

3.2 格式化第一个 NameNode(仅在 master)

# 如果已有数据,先备份!否则会丢失
hdfs namenode -format

3.3 启动 master的 NameNode

hdfs --daemon start namenode

3.4 在 slave1上同步元数据

hdfs namenode -bootstrapStandby

3.5 初始化 HA 状态到 ZooKeeper(任意NameNode 节点,即master和slave1其一)

hdfs zkfc -formatZK

步骤 4:启动整个 HA 集群

在 master:

start-dfs.sh    # 会启动 NN、DN、JN、ZKFC
start-yarn.sh   # RM 在 hadoop01(暂不配 YARN HA)

在 slave1:

# 如果 start-dfs.sh 没自动启动 standby NN,手动启(通常不需要)
hdfs --daemon start namenode

步骤 5:验证 HA

5.1 查看 NameNode 状态

hdfs haadmin -getServiceState nn1  # 应返回 active
hdfs haadmin -getServiceState nn2  # 应返回 standby

5.2 Web UI

  • http://master:9870 → 显示 Active
  • http://slave1:9870 → 显示 Standby

5.3 模拟故障切换

# 在 hadoop01 上杀死 NameNode
pkill -f NameNode

# 等待几秒后检查
hdfs haadmin -getServiceState nn2  # 应变为 active

恢复后,原 active 不会自动抢回(避免脑裂),需手动或配置自动恢复策略。

三、启动集群

初次启动时,可根据上面的内容。当机器关机之后,如何快速启动?

切换到hadoop用户(所有机器都需要)

su - hadoop

启动Zookeeper(所有机器都需要)

./zookeeper/bin/zkServer.sh start

查看Zookeeper集群状态

./zookeeper/bin/zkServer.sh status

使用jps查看

jps
1403 Jps
1308 QuorumPeerMain

启动hdfs(仅在Master机器执行)

start-dfs.sh
Starting namenodes on [master slave1]
Starting datanodes
Starting journal nodes [slave2 slave1 master]
Starting ZK Failover Controllers on NN hosts [master slave1]

验证hdfs,使用jps命令

jps

master节点

1795 JournalNode
2085 Jps
2005 DFSZKFailoverController
1308 QuorumPeerMain
1566 NameNode

slave1节点

1808 DFSZKFailoverController
1861 Jps
1273 QuorumPeerMain
1451 NameNode
1663 JournalNode

slave2节点

1457 DataNode
1570 JournalNode
1270 QuorumPeerMain
1647 Jps

启动yarn(仅在Master机器执行)

start-yarn.sh
Starting resourcemanager
Starting nodemanagers

验证yarn,使用jps命令

jps

master节点

2512 Jps
1795 JournalNode
2005 DFSZKFailoverController
2188 ResourceManager
1308 QuorumPeerMain
1566 NameNode

slave1节点

1808 DFSZKFailoverController
1941 NodeManager
2105 Jps
1273 QuorumPeerMain
1451 NameNode
1663 JournalNode

slave2节点

1457 DataNode
1570 JournalNode
1718 NodeManager
1270 QuorumPeerMain
1847 Jps