系列文章目录
- 第一章 【大数据环境安装指南】 JDK安装
- 第二章 【大数据环境安装指南】 Python安装
- 第三章 【大数据环境安装指南】VMware虚拟机静态IP及多IP配置
- 第四章 【大数据环境安装指南】 Flume图文安装教程
文章目录
- 系列文章目录
- 前言
- 一、 核心架构说明
- 二、 环境准备(所有节点执行)
- 2.1 服务器规划(3 节点)
- 2.2 基础环境初始化
-
-
- 2.2.1 关闭防火墙和 SELinux(所有节点)
- 2.2.2 配置主机名和 hosts 映射
- 2.2.3 安装 JDK(Hadoop 依赖 Java)
- 2.2.4 关闭 swap(Hadoop 推荐,避免性能损耗)
- 2.2.5 创建普通用户SSH配置免密登录:
-
- 三、部署 ZooKeeper 集群(3个 节点)
-
- 3.1 下载
- 3.2 解压
- 3.3 配置环境变量
- 3.4 修改配置
- 3.5 创建 myid 文件(各 Zookeeper 节点)
- 3.6 启动 ZooKeeper 集群(所有 Zookeeper 节点)
- 四、Hadoop环境搭建
-
- 3.1 下载并解压
- 3.2 配置环境变量(主、从节点都需要操作)
- 3.3 Hadoop HA 核心配置
- 3.4 分发程序
- 五、 初始化并启动 Hadoop HA 集群
-
- 5.1 初始化 JournalNode(所有 JournalNode 节点)
- 5.2 初始化 NameNode(仅 node1 执行)
- 5.3 启动 HDFS 集群(node1 执行)
- 5.4 启动 YARN 集群(node1 执行)
- 六、HA 集群验证
-
- 6.1 测试 HDFS 读写
- 6.2 测试故障自动切换
- 七、 Web UI 访问
前言
操作系统环境:Centos 7、Rocky 9 、Almalinux 9、openEuler-25 Hadoop版本:3.4.2 zookeeper版本:3.8.4
Hadoop HA 集群的核心目标是解决 NameNode(NN)和 ResourceManager(RM)的单点故障问题,通过 ZooKeeper 实现 Active/Standby 节点的自动切换,结合 JournalNode(JN)同步 NN 元数据,最终实现集群无单点故障。以下是生产级 3 节点集群的完整搭建指南:
一、 核心架构说明
| NameNode HA | 2 个 NN(Active/Standby),通过 ZKFC(ZooKeeper Failover Controller)实现自动切换 |
| JournalNode | 3 个 JN 节点,同步 Active NN 的 edits 日志,Standby NN 实时读取以保持元数据一致 |
| ZooKeeper | 存储集群状态、选举 Active NN/RM、触发故障转移 |
| ResourceManager HA | 2 个 RM 节点,通过 ZK 存储状态,实现 Active/Standby 自动切换 |
| DataNode/NodeManager | 多节点部署,提供数据存储和任务执行能力 |
Zookeeper 版本与 Hadoop版本的兼容性问题: Hadoop/YARN 对 ZK 版本有严格依赖,高版本 Hadoop 使用的 Curator 客户端可能调用了低版本 ZK 不支持的 API,反之亦然。 查看 Hadoop 依赖的 Curator/ZK 客户端版本:
# 进入Hadoop lib目录,查找curator和zk客户端jar包
ls $HADOOP_HOME/share/hadoop/common/lib | grep -E "curator|zookeeper"
hadoop采用的是3.4.2版本,通过查找curator和zookeeper客户端jar包,建议使用3.8.4版本的zookeeper,不要使用3.4.14版本的zookeeper,会有兼容性问题出现。
二、 环境准备(所有节点执行)
2.1 服务器规划(3 节点)
| 192.168.3.129 | node1 | Active NN、RM、DN、JN、ZK、ZKFC | 50070(NN)、8088(RM) |
| 192.168.3.130 | node2 | Standby NN、RM、DN、JN、ZK、ZKFC | 50070(NN)、8088(RM) |
| 192.168.3.131 | node3 | DN、JN、ZK、NM | 8485(JN)、2181(ZK) |
2.2 基础环境初始化
2.2.1 关闭防火墙和 SELinux(所有节点)
# 临时关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭SELinux
setenforce 0 # 临时
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config # 永久
2.2.2 配置主机名和 hosts 映射
# node1节点
hostnamectl set-hostname node1
# node2节点
hostnamectl set-hostname node2
# node3节点
hostnamectl set-hostname node3
vim /etc/hosts
# 添加以下内容
192.168.3.129 node1
192.168.3.130 node2
192.168.3.131 node3
2.2.3 安装 JDK(Hadoop 依赖 Java)
Hadoop 3.x 推荐 JDK 8(OpenJDK 或 Oracle JDK),需要预先安装,安装步骤详见:: 【大数据环境安装指南】 JDK安装
2.2.4 关闭 swap(Hadoop 推荐,避免性能损耗)
# 临时关闭
swapoff -a
# 永久关闭(注释swap分区)
vi /etc/fstab
# 注释掉包含swap的行,例如:
# /dev/mapper/centos-swap swap swap defaults 0 0
2.2.5 创建普通用户SSH配置免密登录:
Hadoop 组件之间需要基于 SSH 进行通讯。
useradd -m hadoop
passwd hadoop # 设置密码(如hadoop123)
# 在/usr/local目录下新建app目录作为应用安装目录
mkdir /usr/local/app
#app属主授权给hadoop用户
chown -R hadoop:hadoop /usr/local/app
mkdir /usr/local/app
#app属主授权给hadoop用户
chown -R hadoop:hadoop /usr/local/app
echo "hadoop ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
#切换到hadoop用户,生成密钥:
su – hadoop
ssh-keygen -t rsa # 一路回车,生成密钥
执行命令会提示相关操作,默认按回车就好 
cd ~/.ssh

# 写入公匙到授权文件
cat id_rsa.pub >> authorized_keys
# 授权给node1(和localhost是同一台机器,可省略,但建议加)
ssh-copy-id node1
ssh-copy-id node2
ssh-copy-id node3
chmod 600 authorized_keys
restorecon -R ~/.ssh
ssh node2
若直接进入node2主机的命令行,说明免密登录配置完成。
三、部署 ZooKeeper 集群(3个 节点)
3.1 下载
下载对应版本 Zookeeper,这里我下载的版本 3.8.4。官方下载地址:https://archive.apache.org/dist/zookeeper/
Zookeeper 有两种安装包: ❌ 源码包:文件名如 apache-zookeeper-3.8.4.tar.gz(无 -bin 后缀),仅含源码,无编译后的 class 文件; ✅ 二进制包:文件名如 apache-zookeeper-3.8.4-bin.tar.gz(带 -bin 后缀),包含可直接运行的 class 文件。 我们需要下载二进制包:
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
3.2 解压
zookeeper解压到/usr/local/app目录下,没有app目录的需要新建
#解压
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz -C /usr/local/app/
#进行软链接
ln -s apache-zookeeper-3.8.4-bin/ zookeeper
3.3 配置环境变量
修改/etc/profile文件
vim /etc/profile
添加如下环境变量:
export ZOOKEEPER_HOME=/usr/local/app/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH
环境变量立即生效:
source /etc/profile
3.4 修改配置
进入安装目录的 conf/ 目录下,拷贝配置样本并进行修改:
# 进入conf目录
cd /usr/local/app/zookeeper/conf/
# 拷贝配置文件
cp zoo_sample.cfg zoo.cfg
# 修改配置文件
vim zoo.cfg
配置 zoo.cfg内容如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/app/zookeeper/data
dataLogDir=/usr/local/app/zookeeper/log
clientPort=2181
# 集群配置
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
# 自动清理日志
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
配置参数说明:
tickTime:用于计算的基础时间单元。比如 session 超时:N*tickTime;
initLimit:用于集群,允许从节点连接并同步到 master 节点的初始化连接时间,以 tickTime 的倍数来表示;
syncLimit:用于集群, master 主节点与从节点之间发送消息,请求和应答时间长度(心跳机制);
dataDir:数据存储位置;
dataLogDir:日志目录;
clientPort:用于客户端连接的端口,默认 2181
3.5 创建 myid 文件(各 Zookeeper 节点)
# node1
mkdir -p /usr/local/app/zookeeper/data
mkdir -p /usr/local/app/zookeeper/logs
echo "1" > /usr/local/app/zookeeper/data/myid
# node2
mkdir -p /usr/local/app/zookeeper/data
mkdir -p /usr/local/app/zookeeper/logs
echo "2" > /usr/local/app/zookeeper/data/myid
# node3
mkdir -p /usr/local/app/zookeeper/data
mkdir -p /usr/local/app/zookeeper/logs
echo "3" > /usr/local/app/zookeeper/data/myid
3.6 启动 ZooKeeper 集群(所有 Zookeeper 节点)
# 所有ZK节点执行
/usr/local/app/zookeepe/bin/zkServer.sh start
# 验证状态(node1/2/3分别执行,应有1个leader、2个follower)
/usr/local/app/zookeeper/bin/zkServer.sh status
# 正常输出:Mode: leader 或 Mode: follower
可以使用 JPS 验证进程是否已经启动,出现 QuorumPeerMain 则代表启动成功。
jps

四、Hadoop环境搭建
3.1 下载并解压
- 清华镜像: https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/
- 阿里镜像: https://mirrors.aliyun.com/apache/hadoop/common/
#文件解压到app目录下
tar -zxvf hadoop-3.4.2.tar.gz -C /usr/local/app
#创建软链接
ln -s hadoop-3.4.2 hadoop
3.2 配置环境变量(主、从节点都需要操作)
vim /etc/profile
配置环境变量,添加如下内容:
export HADOOP_HOME=/usr/local/app/hadoop
export PATH=${HADOOP_HOME}/bin:$PATH
执行 source 命令,使得配置的环境变量立即生效:
source /etc/profile
3.3 Hadoop HA 核心配置
Hadoop HA 配置主要修改 $HADOOP_HOME/etc/hadoop 下的 6 个核心文件,所有配置需同步到所有节点。
cd ${HADOOP_HOME}/etc/hadoop/
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!– 指定HDFS的nameservice为mycluster(自定义) –>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!– Hadoop临时目录 –>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
</property>
<!– ZooKeeper地址 –>
<property>
<name>ha.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<!– 开启Hadoop回收站(可选) –>
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
</configuration>

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!– 开启HDFS 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的RPC地址 –>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>node1:8020</value>
</property>
<!– nn1的HTTP地址 –>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node1:50070</value>
</property>
<!– nn2的RPC地址 –>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node2:8020</value>
</property>
<!– nn2的HTTP地址 –>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node2:50070</value>
</property>
<!– NameNode元数据存储到JournalNode的路径 –>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485/mycluster</value>
</property>
<!– JournalNode数据存储目录 –>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/journaldata</value>
</property>
<!– 开启自动故障切换 –>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</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.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
<!– ssh免密登录(隔离机制依赖) –>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!– 关闭权限检查(测试环境) –>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
<!– DataNode数据存储目录 –>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/datanode</value>
</property>
</configuration>

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!– 开启YARN HA –>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!– RM集群ID –>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</value>
</property>
<!– RM节点ID –>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!– rm1地址 –>
<property>
<!– RM1 的服务地址 –>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node1</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>node1:8032</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>node1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>node1:8031</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>node1:8030</value>
</property>
<!– rm2地址 –>
<property>
<!– RM2 的服务地址 –>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node2</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>node2:8032</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>node2:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>node2:8031</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>node2:8030</value>
</property>
<!– ZooKeeper地址 –>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<!– 开启自动恢复 –>
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!– 恢复机制 –>
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!– 开启NodeManager本地服务 –>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!– 开启内存检查 –>
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
</configuration>

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!– 指定MapReduce运行在YARN上 –>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!– 开启MapReduce HA –>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/app/hadoop</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/app/hadoop</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/app/hadoop</value>
</property>
</configuration>

#修改hadoop-env.sh文件
vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh
# 添加/修改以下内容
export JAVA_HOME=/usr/local/jdk8/
export HDFS_NAMENODE_USER="hadoop"
export HDFS_DATANODE_USER="hadoop"
export HDFS_JOURNALNODE_USER="hadoop"
export HDFS_ZKFC_USER="hadoop"
export YARN_RESOURCEMANAGER_USER="hadoop"
export YARN_NODEMANAGER_USER="hadoop"
# 解决ZooKeeper连接超时
export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true"

#修改workers文件
vim $HADOOP_HOME/etc/hadoop/workers
# 添加/修改以下内容
node1
node2
node3
3.4 分发程序
将 Hadoop 安装包分发到其他两台服务器,分发后建议在这两台服务器上也配置一下 Hadoop 的环境变量。
# 将安装包分发到node2
scp -r /usr/local/app/hadoop node2:/usr/local/app
# 将安装包分发到node3
scp -r /usr/local/app/hadoop node3:/usr/local/app
在从节点node2、node3的服务器也要配置下hadoop环境变量, 编辑/etc/profile文件,增加如下内容:
#编辑/etc/profile文件
vim /etc/profile
#添加/修改如下内容
export HADOOP_HOME=/usr/local/app/hadoop
export PATH=${HADOOP_HOME}/bin:$PATH
执行 source 命令,使得配置的环境变量立即生效:
source /etc/profile
五、 初始化并启动 Hadoop HA 集群
5.1 初始化 JournalNode(所有 JournalNode 节点)
# 创建JournalNode数据目录(所有节点)
mkdir -p /home/hadoop/journaldata
# 启动JournalNode(node1、node2、node3节点)
hdfs –daemon start journalnode
# 验证启动状态
jps | grep JournalNode # 应有JournalNode进程

5.2 初始化 NameNode(仅 node1 执行)
# 格式化NameNode(node1执行)
hdfs namenode -format
# 启动node1的NameNode(node1执行)
hdfs –daemon start namenode
# 将node1的NameNode元数据同步到node2(node2执行)
hdfs namenode -bootstrapStandby
# 格式化ZooKeeper(仅node1执行,初始化HA状态)
hdfs zkfc -formatZK
5.3 启动 HDFS 集群(node1 执行)
#进入$HADOOP_HOME/sbin目录
cd $HADOOP_HOME/sbin
# 启动所有HDFS进程
./start-dfs.sh
# 验证进程(node1应有NameNode、ZKFC、DataNode、JournalNode;node2应有Standby NameNode、ZKFC、DataNode、JournalNode;node3应有DataNode、JournalNode)
jps
验证进程:
-
node 1

-
node 2

-
node 3

# 查看NameNode状态(应有1个Active,1个Standby)
hdfs haadmin -getServiceState nn1 # 输出active/standby
hdfs haadmin -getServiceState nn2 # 输出standby/active

5.4 启动 YARN 集群(node1 执行)
#进入$HADOOP_HOME/sbin目录
cd $HADOOP_HOME/sbin
# 启动所有YARN进程(node1 执行)
./start-yarn.sh
# 启动备用ResourceManager(node1、node2执行,确保RM HA)
yarn –daemon start resourcemanager
# node1、node2验证RM状态
yarn rmadmin -getServiceState rm1 # 输出active/standby
yarn rmadmin -getServiceState rm2 # 输出standby/active

六、HA 集群验证
6.1 测试 HDFS 读写
# 创建目录
hdfs dfs -mkdir /test
# 上传文件
hdfs dfs -put $HADOOP_HOME/README.txt /test
# 查看文件
hdfs dfs -ls /test
# 下载文件
hdfs dfs -get /test/README.txt ./

6.2 测试故障自动切换
(1)、手动停止 Active NameNode(如 node1 的 nn1):
# node1执行
hdfs –daemon stop namenode
# 验证切换(node2的nn2应自动变为Active)
hdfs haadmin -getServiceState nn2 # 输出active

(2)、恢复原 NameNode:
# node1执行
hdfs –daemon start namenode
# 验证状态(node1变为Standby)
hdfs haadmin -getServiceState nn1 # 输出standby
(3)、测试 ResourceManager 切换:
# 停止Active RM(如node1的rm1)
yarn –daemon stop resourcemanager
# 验证切换(node2的rm2变为Active)
yarn rmadmin -getServiceState rm2 # 输出active

七、 Web UI 访问
Active NameNode: 访问http://node1:50070 或 http://node2:50070(显示 Active 的节点); 
ResourceManager: http://node1:8088 或 http://node2:8088(显示 Active 的节点)。 






