文章目录
- 前言
- 一、 核心架构说明
- 二、 环境准备(所有节点执行)
- 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 节点)
| 节点 IP | 主机名 | 核心角色 | 关键端口 |
|---|---|---|---|
| 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# 关闭SELinuxsetenforce0# 临时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- 配置 hosts 文件(所有节点):
vim/etc/hosts# 添加以下内容192.168.3.129 node1192.168.3.130 node2192.168.3.131 node32.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 02.2.5 创建普通用户SSH配置免密登录:
Hadoop 组件之间需要基于 SSH 进行通讯。
- 创建hadoop用户
Hadoop 官方不建议用 root 运行集群(安全风险 + 权限混乱),核心思路是创建专属普通用户(如 hadoop),并赋予相关目录权限,全程以该用户操作。
useradd-m hadooppasswdhadoop# 设置密码(如hadoop123)# 在/usr/local目录下新建app目录作为应用安装目录mkdir/usr/local/app#app属主授权给hadoop用户chown-R hadoop:hadoop /usr/local/app- 在/usr/local目录下新建app目录
mkdir/usr/local/app#app属主授权给hadoop用户chown-R hadoop:hadoop /usr/local/app- 赋予hadoop用户sudo权限(可选,方便后续操作)
echo"hadoop ALL=(ALL) NOPASSWD:ALL">>/etc/sudoers- 生成密钥(
所有节点执行,一路回车):
#切换到hadoop用户,生成密钥:su- hadoop ssh-keygen -t rsa# 一路回车,生成密钥执行命令会提示相关操作,默认按回车就好
- 授权
进入~/.ssh目录下,查看生成的公匙和私匙
cd~/.ssh- 互传公钥(
node1执行,将公钥分发到所有节点):
# 写入公匙到授权文件catid_rsa.pub>>authorized_keys# 授权给node1(和localhost是同一台机器,可省略,但建议加)ssh-copy-id node1 ssh-copy-id node2 ssh-copy-id node3chmod600authorized_keys- 检查 SELinux / 防火墙:若开启 SELinux,需确保 SSH 目录上下文正确,执行如下命令:
restorecon -R ~/.ssh- 验证免密登录是否生效,执行以下命令验证(无需输入密码即表示成功):
sshnode2若直接进入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 文件。
我们需要下载二进制包:
wgethttps://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz3.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/ zookeeper3.3 配置环境变量
修改/etc/profile文件
vim/etc/profile添加如下环境变量:
exportZOOKEEPER_HOME=/usr/local/app/zookeeperexportPATH=$ZOOKEEPER_HOME/bin:$PATH环境变量立即生效:
source/etc/profile3.4 修改配置
进入安装目录的conf/目录下,拷贝配置样本并进行修改:
# 进入conf目录cd/usr/local/app/zookeeper/conf/# 拷贝配置文件cpzoo_sample.cfg zoo.cfg# 修改配置文件vimzoo.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:用于客户端连接的端口,默认 21813.5 创建 myid 文件(各 Zookeeper 节点)
# node1mkdir-p /usr/local/app/zookeeper/datamkdir-p /usr/local/app/zookeeper/logsecho"1">/usr/local/app/zookeeper/data/myid# node2mkdir-p /usr/local/app/zookeeper/datamkdir-p /usr/local/app/zookeeper/logsecho"2">/usr/local/app/zookeeper/data/myid# node3mkdir-p /usr/local/app/zookeeper/datamkdir-p /usr/local/app/zookeeper/logsecho"3">/usr/local/app/zookeeper/data/myid3.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 下载并解压
- 访问官方下载页面,打开 Apache Hadoop 官网下载地址:https://hadoop.apache.org/releases.html
- 直接访问镜像站(国内下载更快):
- 清华镜像:
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 hadoop3.2 配置环境变量(主、从节点都需要操作)
vim/etc/profile配置环境变量,添加如下内容:
exportHADOOP_HOME=/usr/local/app/hadoopexportPATH=${HADOOP_HOME}/bin:$PATH执行source命令,使得配置的环境变量立即生效:
source/etc/profile3.3 Hadoop HA 核心配置
Hadoop HA 配置主要修改 $HADOOP_HOME/etc/hadoop 下的 6 个核心文件,所有配置需同步到所有节点。
cd${HADOOP_HOME}/etc/hadoop/- core-site.xml
<?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>- hdfs-site.xml
指定副本系数和临时文件存储位置:
<?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>- yarn-site.xml
<?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>- mapred-site.xml
<?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
#修改hadoop-env.sh文件vim$HADOOP_HOME/etc/hadoop/hadoop-env.sh# 添加/修改以下内容exportJAVA_HOME=/usr/local/jdk8/exportHDFS_NAMENODE_USER="hadoop"exportHDFS_DATANODE_USER="hadoop"exportHDFS_JOURNALNODE_USER="hadoop"exportHDFS_ZKFC_USER="hadoop"exportYARN_RESOURCEMANAGER_USER="hadoop"exportYARN_NODEMANAGER_USER="hadoop"# 解决ZooKeeper连接超时exportHADOOP_OPTS="-Djava.net.preferIPv4Stack=true"- 编辑workers文件
配置所有从属节点的主机名或 IP 地址,由于是单机版本,所以指定本机即可,添加如下主机名:
#修改workers文件vim$HADOOP_HOME/etc/hadoop/workers# 添加/修改以下内容node1 node2 node33.4 分发程序
将 Hadoop 安装包分发到其他两台服务器,分发后建议在这两台服务器上也配置一下 Hadoop 的环境变量。
# 将安装包分发到node2scp-r /usr/local/app/hadoop node2:/usr/local/app# 将安装包分发到node3scp-r /usr/local/app/hadoop node3:/usr/local/app在从节点node2、node3的服务器也要配置下hadoop环境变量,
编辑/etc/profile文件,增加如下内容:
#编辑/etc/profile文件vim/etc/profile#添加/修改如下内容exportHADOOP_HOME=/usr/local/app/hadoopexportPATH=${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|grepJournalNode# 应有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 -formatZK5.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/standbyhdfs haadmin -getServiceState nn2# 输出standby/active5.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状态yarnrmadmin -getServiceState rm1# 输出active/standbyyarnrmadmin -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)yarnrmadmin -getServiceState rm2# 输出active七、 Web UI 访问
Active NameNode:
访问http://node1:50070 或 http://node2:50070(显示 Active 的节点);ResourceManager:
http://node1:8088 或 http://node2:8088(显示 Active 的节点)。