下面开始配置HDFS 的HA
HA集群规划
namenode datanode journalnode zkfc zookeeper
bigdata01 yes yes yes yes
bigdata02 yes yes yes yes yes
bigdata03 yes yes yes yes
解释:针对HDFS的HA集群,在这里我们只需要启动HDFS相关的进程即可,YARN相关的进程可以不启动,它们两个的进程本来就是相互独立的。
在HDFS的HA集群中,就不需要启动SecondaryNameNode进程了
namenode:hdfs的主节点
datanode:hdfs的从节点
journalnode:JournalNode进程,用来同步Edits信息的
zkfc(DFSZKFailoverController):监视namenode的状态,负责切换namenode节点的状态
zookeeper(QuorumPeerMain):保存ha集群的节点状态信息
环境准备:三个节点
bigdata01 192.168.182.100
bigdata02 192.168.182.101
bigdata03 192.168.182.102
每个节点的基础环境都要先配置好,先把ip、hostname、firewalld、ssh免密码登录、host、免密码登录,JDK这些基础环境配置好
我们目前使用的这几台机器之前已经搭建过分布式集群,所以这些基础环境都是没有问题的
但是注意:有一点还需要完善一下,由于namenode在进行故障切换的时候,需要在两个namenode节点之间互相使用ssh进行连接,所以需要实现这两个namenode之间的互相免密码登录,目前我们只实现了bigdata01免密码登录到bigdata02,所以还需要实现bigdata02免密码登录到bigdata01,这一步如果不做,后期无法实现namenode故障自动转移。
[root@bigdata02 hadoop]# scp ~/.ssh/authorized_keys bigdata01:~/
root@bigdata01's password: 输入密码
authorized_keys 100% 792 456.2KB/s 00:00
[root@bigdata01 hadoop]# cat ~/authorized_keys >> ~/.ssh/authorized_keys
然后验证一下bigdata02是否可以免密码登录bigdata01,只要可以不输入密码就能连接进去就说明免密码登录搞定了。
[root@bigdata02 hadoop]# ssh bigdata01
Last login: Fri Feb 6 23:54:41 2026 from 192.168.182.1
接着把bigdata01、bigdata02、bigdata03中之前安装的hadoop删掉,删除解压的目录,以及hadoop_repo目录。
注意:我们需要把bigdata01、bigdata02、bigdata03节点中/data目录下的hadoop_repo目录和/data/soft下的hadoop-3.2.0目录删掉,恢复这些节点的环境,这里面记录的有之前集群的一些信息。
[root@bigdata01 ~]# rm -rf /data/soft/hadoop-3.2.0
[root@bigdata01 ~]# rm -rf /data/hadoop_repo
[root@bigdata02~]# rm -rf /data/soft/hadoop-3.2.0
[root@bigdata02 ~]# rm -rf /data/hadoop_repo
[root@bigdata03 ~]# rm -rf /data/soft/hadoop-3.2.0
[root@bigdata04 ~]# rm -rf /data/hadoop_repo
我们在这里需要使用到zookeeper这个组件,所以先把它安装起来。
集群节点规划,使用三个节点搭建一个zookeeper集群
bigdata01
bigdata02
bigdata03
首先在bigdata01节点上配置zookeeper
解压
[root@bigdata01 soft]# tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz
修改配置
将zoo_sample.cfg重命名为zoo.cfg
然后修改zoo.cfg中的dataDir参数的值,dataDir指向的目录存储的是zookeeper的核心数据,所以这个目录不能使用tmp目录,然后增加server.0、server.1、server.2这三行内容
[root@bigdata01 soft]# cd apache-zookeeper-3.5.8-bin/conf/
[root@bigdata01 conf]# mv zoo_sample.cfg zoo.cfg
加到最后面
[root@bigdata01 conf]# vi zoo.cfg
dataDir=/data/soft/apache-zookeeper-3.5.8-bin/data
server.0=bigdata01:2888:3888
server.1=bigdata02:2888:3888
server.2=bigdata03:2888:3888
创建目录保存myid文件,并且向myid文件中写入内容
myid中的值其实是和zoo.cfg中server后面指定的编号是一一对应的
编号0对应的是bigdata01这台机器,所以在这里指定0
在这里使用echo 和 重定向 实现数据写入
[root@bigdata01 conf]#cd /data/soft/apache-zookeeper-3.5.8-bin
[root@bigdata01 apache-zookeeper-3.5.8-bin]# mkdir data
[root@bigdata01 apache-zookeeper-3.5.8-bin]# cd data
[root@bigdata01 data]# echo 0 > myid
把修改好配置的zookeeper拷贝到其它两个节点
[root@bigdata01 soft]# scp -rq apache-zookeeper-3.5.8-bin bigdata02:/data/soft/
[root@bigdata01 soft]# scp -rq apache-zookeeper-3.5.8-bin bigdata03:/data/soft/
修改bigdata02和bigdata03上zookeeper中myid文件的内容
首先修改bigdata02节点上的myid文件
[root@bigdata02 ~]# cd /data/soft/apache-zookeeper-3.5.8-bin/data/
[root@bigdata02 data]# echo 1 > myid
然后修改bigdata03节点上的myid文件
[root@bigdata03 ~]# cd /data/soft/apache-zookeeper-3.5.8-bin/data/
[root@bigdata03 data]# echo 2 > myid
启动zookeeper集群
分别在bigdata01、bigdata02、bigdata03上启动zookeeper进程
在bigdata01上启动
[root@bigdata01 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
在bigdata02上启动
[root@bigdata02 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
在bigdata03上启动
[root@bigdata03 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
验证
分别在bigdata01、bigdata02、bigdata03上执行jps命令验证是否有QuorumPeerMain进程
如果都有就说明zookeeper集群启动正常了
如果没有就到对应的节点的logs目录下查看zookeeper*-*.out日志文件
执行bin/zkServer.sh status 命令会发现有一个节点显示为leader,其他两个节点为follower
[root@bigdata01 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
[root@bigdata02 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
[root@bigdata03 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /data/soft/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
接下来我们来配置Hadoop集群
先在bigdata01节点上进行配置
解压hadoop安装包
[root@bigdata01 soft]# tar -zxvf hadoop-3.2.0.tar.gz
修改hadoop相关配置文件
进入配置文件所在目录
[root@bigdata01 soft]# cd hadoop-3.2.0/etc/hadoop/
[root@bigdata01 hadoop]#
首先修改hadoop-env.sh文件,在文件末尾增加环境变量信息
[root@bigdata01 hadoop]# vi hadoop-env.sh
export JAVA_HOME=/data/soft/jdk1.8
export HADOOP_LOG_DIR=/data/hadoop_repo/logs/hadoop
修改core-site.xml文件
[root@bigdata01 hadoop]# vi core-site.xml
<configuration>
# mycluster是集群的逻辑名称,需要和hdfs-site.xml中dfs.nameservices值一致
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop_repo</value>
</property>
# 用户角色配置,不配置此项会导致web页面报错
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</value>
</property>
# zookeeper集群地址
<property>
<name>ha.zookeeper.quorum</name>
<value>bigdata01:2181,bigdata02:2181,bigdata03:2181</value>
</property>
</configuration>
修改hdfs-site.xml文件
[root@bigdata01 hadoop]# vi hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
# 自定义的集群名称
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
# 所有的namenode列表,逻辑名称,不是namenode所在的主机名
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
# namenode之间用于RPC通信的地址,value填写namenode所在的主机地址
# 默认端口8020,注意mycluster与nn1要和前面的配置一致
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>bigdata01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>bigdata02:8020</value>
</property>
# namenode的web访问地址,默认端口9870
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>bigdata01:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>bigdata02:9870</value>
</property>
# journalnode主机地址,最少三台,默认端口8485
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://bigdata01:8485;bigdata02:8485;bigdata03:8485/mycluster</value>
</property>
# 故障时自动切换的实现类
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
# 故障时相互操作方式(namenode要切换active和standby),使用ssh方式
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
# 修改为自己用户的ssh key存放地址
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
# namenode日志文件输出路径,即journalnode读取变更的位置
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/hadoop_repo/journalnode</value>
</property>
# 启用自动故障转移
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
mapred-site.xml和yarn-site.xml在这暂时就不修改了,因为我们只需要启动hdfs相关的服务。
修改workers文件,增加所有从节点的主机名,一个一行
[root@bigdata01 hadoop]# vi workers
bigdata02
bigdata03
修改启动脚本
修改start-dfs.sh,stop-dfs.sh这两个脚本文件,在文件前面增加如下内容
[root@bigdata01 hadoop]# cd /data/soft/hadoop-3.2.0/sbin
[root@bigdata01 sbin]# vi start-dfs.sh
HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_ZKFC_USER=root
HDFS_JOURNALNODE_USER=root
[root@bigdata01 sbin]# vi stop-dfs.sh
HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_ZKFC_USER=root
HDFS_JOURNALNODE_USER=root
start-yarn.sh,stop-yarn.sh这两个脚本暂时也不需要修改了,因为不启动YARN相关的进程用不到。
把bigdata01节点上将修改好配置的安装包拷贝到其他两个从节点
[root@bigdata01 sbin]# cd /data/soft/
[root@bigdata01 soft]# scp -rq hadoop-3.2.0 bigdata02:/data/soft/
[root@bigdata01 soft]# scp -rq hadoop-3.2.0 bigdata03:/data/soft/
格式化HDFS【此步骤只需要在第一次配置HA集群的时候操作一次即可】
注意:此时在格式化HDFS之前需要先启动所有的journalnode
[root@bigdata01 hadoop-3.2.0]# bin/hdfs --daemon start journalnode
[root@bigdata02 hadoop-3.2.0]# bin/hdfs --daemon start journalnode
[root@bigdata03 hadoop-3.2.0]# bin/hdfs --daemon start journalnode
接下来就可以对HDFS进行格式化了,此时在哪个namenode节点上操作都可以(bigdata01或者bigdata02),在这我们使用bigdata01
能看到has been successfully formatted就说明hdfs格式化成功了
[root@bigdata01 hadoop-3.2.0]# bin/hdfs namenode -format
....
....
2026-02-07 00:35:06,212 INFO common.Storage: Storage directory /data/hadoop_repo/dfs/name has been successfully formatted.
2026-02-07 00:35:06,311 INFO namenode.FSImageFormatProtobuf: Saving image file /data/hadoop_repo/dfs/name/current/fsimage.ckpt_0000000000000000000 using no compression
2026-02-07 00:35:06,399 INFO namenode.FSImageFormatProtobuf: Image file /data/hadoop_repo/dfs/name/current/fsimage.ckpt_0000000000000000000 of size 399 bytes saved in 0 seconds .
2026-02-07 00:35:06,405 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
2026-02-07 00:35:06,432 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at bigdata01/192.168.182.100
************************************************************/
然后启动此namenode进程
[root@bigdata01 hadoop-3.2.0]# bin/hdfs --daemon start namenode
接下来在另一个namenode节点(bigdata02)上同步信息,看到下面的信息,则说明同步成功
[root@bigdata02 hadoop-3.2.0]# bin/hdfs namenode -bootstrapStandby
....
....
=====================================================
About to bootstrap Standby ID nn2 from:
Nameservice ID: mycluster
Other Namenode ID: nn1
Other NN's HTTP address: http://bigdata01:9870
Other NN's IPC address: bigdata01/192.168.182.100:8020
Namespace ID: 1820763709
Block pool ID: BP-1332041116-192.168.182.100-1770395706205
Cluster ID: CID-c12130ca-3a7d-4722-93b0-a79b0df3ed84
Layout version: -65
isUpgradeFinalized: true
=====================================================
2026-02-07 00:39:38,594 INFO common.Storage: Storage directory /data/hadoop_repo/dfs/name has been successfully formatted.
2026-02-07 00:39:38,654 INFO namenode.FSEditLog: Edit logging is async:true
2026-02-07 00:39:38,767 INFO namenode.TransferFsImage: Opening connection to http://bigdata01:9870/imagetransfer?getimage=1&txid=0&storageInfo=-65:1820763709:1770395706205:CID-c12130ca-3a7d-4722-93b0-a79b0df3ed84&bootstrapstandby=true
2026-02-07 00:39:38,854 INFO common.Util: Combined time for file download and fsync to all disks took 0.00s. The file download took 0.00s at 0.00 KB/s. Synchronous (fsync) write to disk of /data/hadoop_repo/dfs/name/current/fsimage.ckpt_0000000000000000000 took 0.00s.
2026-02-07 00:39:38,855 INFO namenode.TransferFsImage: Downloaded file fsimage.ckpt_0000000000000000000 size 399 bytes.
2026-02-07 00:39:38,894 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at bigdata02/192.168.182.101
************************************************************/
格式化zookeeper节点【此步骤只需要在第一次配置HA集群的时候操作一次即可】
在任意一个节点上操作都可以,在这里我使用bigdata01节点
能看到日志中输出Successfully created /hadoop-ha/mycluster in ZK.则说明操作成功
[root@bigdata01 hadoop-3.2.0]# bin/hdfs zkfc -formatZK
....
....
2026-02-07 00:42:17,212 INFO zookeeper.ClientCnxn: Socket connection established to bigdata02/192.168.182.101:2181, initiating session
2026-02-07 00:42:17,220 INFO zookeeper.ClientCnxn: Session establishment complete on server bigdata02/192.168.182.101:2181, sessionid = 0x100001104b00098, negotiated timeout = 10000
2026-02-07 00:42:17,244 INFO ha.ActiveStandbyElector: Successfully created /hadoop-ha/mycluster in ZK.
2026-02-07 00:42:17,249 INFO zookeeper.ZooKeeper: Session: 0x100001104b00098 closed
2026-02-07 00:42:17,251 WARN ha.ActiveStandbyElector: Ignoring stale result from old client with sessionId 0x100001104b00098
2026-02-07 00:42:17,251 INFO zookeeper.ClientCnxn: EventThread shut down for session: 0x100001104b00098
2026-02-07 00:42:17,254 INFO tools.DFSZKFailoverController: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down DFSZKFailoverController at bigdata01/192.168.182.100
************************************************************/
启动HDFS的HA集群
注意:以后启动HDFS的HA集群直接使用这里面的命令即可,不需要再执行4、5步中的操作了
在bigdata01上执行下面命令
[root@bigdata01 hadoop-3.2.0]# sbin/start-dfs.sh
Starting namenodes on [bigdata01 bigdata02]
Last login: Sat Feb 7 00:02:27 CST 2026 on pts/0
bigdata01: namenode is running as process 6424. Stop it first.
Starting datanodes
Last login: Sat Feb 7 00:47:13 CST 2026 on pts/0
Starting journal nodes [bigdata01 bigdata03 bigdata02]
Last login: Sat Feb 7 00:47:13 CST 2026 on pts/0
bigdata02: journalnode is running as process 4864. Stop it first.
bigdata01: journalnode is running as process 6276. Stop it first.
bigdata03: journalnode is running as process 2479. Stop it first.
Starting ZK Failover Controllers on NN hosts [bigdata01 bigdata02]
Last login: Sat Feb 7 00:47:18 CST 2026 on pts/0
验证HA集群
此时访问两个namenode节点的9870端口,其中一个显示为Active,另一个显示为Standby
http://bigdata01:9870/dfshealth.html
http://bigdata02:9870/dfshealth.html
此时我们来手工停掉active状态的namenode,模拟namenode宕机的情况,验证一下另一个standby的namenode是否可以自动切换为active
[root@bigdata01 hadoop-3.2.0]# jps
8758 DFSZKFailoverController
8267 NameNode
1581 QuorumPeerMain
8541 JournalNode
8814 Jps
[root@bigdata01 hadoop-3.2.0]# kill 8267
[root@bigdata01 hadoop-3.2.0]# jps
8758 DFSZKFailoverController
1581 QuorumPeerMain
8541 JournalNode
8845 Jps
此时再刷新查看bigdata02的信息,会发现它的状态变为了active
接着我们再把bigdata01中的namenode启动起来,会发现它的状态变为了standby
[root@bigdata01 hadoop-3.2.0]# bin/hdfs --daemon start namenode
[root@bigdata01 hadoop-3.2.0]# jps
8898 NameNode
8758 DFSZKFailoverController
8967 Jps
1581 QuorumPeerMain
8541 JournalNode
通过前面的操作可以发现,现在的namenode其实就解决了单点故障的问题,实现了高可用。
现在我们再操作HDFS的时候就应该这样操作了。
这里面的mycluster就是在hdfs-site.xml中配置的dfs.nameservices属性的值。
[root@bigdata02 hadoop-3.2.0]# bin/hdfs dfs -ls hdfs://mycluster/
[root@bigdata02 hadoop-3.2.0]# bin/hdfs dfs -put README.txt hdfs://mycluster/
[root@bigdata02 hadoop-3.2.0]# bin/hdfs dfs -ls hdfs://mycluster/ Found 1 items
-rw-r--r-- 2 root supergroup 1361 2026-02-07 00:58 hdfs://mycluster/README.txt
停止HDFS的HA集群
[root@bigdata01 hadoop-3.2.0]# sbin/stop-dfs.sh
Stopping namenodes on [bigdata01 bigdata02]
Last login: Sat Feb 7 00:52:01 CST 2026 on pts/0
Stopping datanodes
Last login: Sat Feb 7 01:03:23 CST 2026 on pts/0
Stopping journal nodes [bigdata01 bigdata03 bigdata02]
Last login: Sat Feb 7 01:03:25 CST 2026 on pts/0
Stopping ZK Failover Controllers on NN hosts [bigdata01 bigdata02]
Last login: Sat Feb 7 01:03:29 CST 2026 on pts/0
停止三个节点上的zookeeper服务
[root@bigdata01 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh stop
[root@bigdata02 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh stop
[root@bigdata03 apache-zookeeper-3.5.8-bin]# bin/zkServer.sh stop