【大数据之Hadoop】三十七、Hadoop HA高可用

1、HA概述

  实现高可用最关键的策略是消除单点故障。HA分成各个组件的HA机制:HDFS的HA和YARN的HA。

  Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。

NameNode主要在以下两个方面影响HDFS集群:

(1)NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启。

(2)NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用。

  HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。

2、HDFS-HA

2.1 HDFS-HA工作机制

通过双或多NameNode消除单点故障。

(1)元数据存储方式:内存中保存一份元数据,日志文件只有Active状态的NameNode节点才能进行写操作,多个NameNode都可以对日志文件进行读操作,共享的日志文件放在一个共享存储中管理。

(2)需要一个状态管理功能模块:实现一个zkfailover,常驻在每一个NameNode所在的节点,每一个zkfailover负责监控自己所在NameNode节点,利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split(脑裂)现象的发生。

(3)必须保证多个NameNode之间能够ssh无密码登录

(4)隔离(Fence),即同一时刻仅仅有一个NameNode对外提供服务

2.2 HDFS-HA自动故障转移机制

  自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。

HA的自动故障转移依赖于ZooKeeper的以下功能:

(1)故障检测:集群中的每个NameNode在ZooKeeper中维护了一个持久会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。

(2)现役NameNode选择:ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果目前现役NameNode崩溃,另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。

  ZKFC是自动故障转移中的另一个新组件,是ZooKeeper的客户端,也监视和管理NameNode的状态。每个运行NameNode的主机也运行了一个ZKFC进程。

ZKFC负责:

(1)健康监测:ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode,只要该NameNode及时地回复健康状态,ZKFC认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。

(2)ZooKeeper会话管理:当本地NameNode是健康的,ZKFC保持一个在ZooKeeper中打开的会话。如果本地NameNode处于active状态,ZKFC也保持一个特殊的znode锁,该锁使用了ZooKeeper对短暂节点的支持,如果会话终止,锁节点将自动删除。

(3)基于ZooKeeper的选择:如果本地NameNode是健康的,且ZKFC发现没有其它的节点当前持有znode锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地NameNode为Active。首先如果必要保护之前的现役NameNode,然后本地NameNode转换为Active状态。

2.3 HDFS-HA集群配置

2.3.1 集群规划

2.3.2 配置Zookeeper集群

(1)解压安装

java 复制代码
//解压zookeeper安装包到/opt/module/目录下
tar -zxvf zookeeper-3.5.7.tar.gz -C /opt/module/

//在/opt/module/zookeeper-3.5.7/目录下创建zkData
mkdir -p zkData

//重命名/opt/module/zookeeper-3.5.7/conf目录下的zoo_sample.cfg为zoo.cfg
mv zoo_sample.cfg zoo.cfg

(2)配置zoo.cfg文件

java 复制代码
vim zoo.cfg

#更改以下
dataDir=/opt/module/zookeeper-3.5.7/zkData

#添加以下
#######################cluster##########################
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888

配置参数解读:Server.A=B:C:D。

A是一个数字,表示这个是第几号服务器;

B是这个服务器的IP地址;

C是这个服务器与集群中的Leader服务器交换信息的端口;

D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

  集群模式下配置一个文件myid,这个文件在zkData目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

java 复制代码
//在/opt/module/zookeeper-3.5.7/zkData下创建一个文件myid,并编辑
vim myid

#在hadoop102添加以下:
2

(3)集群操作

java 复制代码
//分发zookeeper到其他机器上:
xsync zookeeper-3.5.7

//分别在hadoop103、hadoop104的myid文件中修改2为3、4

//在/home/用户名/bin中新建一个文件zk.sh并编辑
vim zk.sh
#添加以下内容:

#!/bin/bash
case $1 in
"start"){
for i in hadoop102 hadoop103 hadoop104
do
 echo ---------- zookeeper $i 启动 ------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
done
};;
"stop"){
for i in hadoop102 hadoop103 hadoop104
do
 echo ---------- zookeeper $i 停止 ------------ 
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
done
};;
"status"){
for i in hadoop102 hadoop103 hadoop104
do
 echo ---------- zookeeper $i 状态 ------------ 
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
done
};;
esac
java 复制代码
//赋予脚本权限:
chmod 777 zk.sh

//启动zookeeper
zk.sh start

//查看状态
zk.sh status

//关闭zookeeper
zk.sh stop

2.3.3 配置HDFS-HA集群

在/opt/下新建文件夹ha,将/opt/module/下的hadoop-3.3.1拷贝到/opt/ha/下

java 复制代码
cd /opt
mkdir ha
cp -r hadoop-3.3.1/ /opt/ha/

配置core-site.xml,删掉之前的配置,添加以下

xml 复制代码
    <!-- 把两个NameNode)的地址组装成一个集群mycluster -->
    <property>
        <name>fs.defaultFS</name>
            <value>hdfs://mycluster</value>
    </property>

    <!-- 指定hadoop运行时产生文件的存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/ha/hadoop-3.3.1/data</value>
    </property>

    <!-- 指定zkfc要连接的zkServer地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
    </property>

配置hdfs-site.xml,删掉之前的配置,添加以下

xml 复制代码
    <!-- NameNode数据存储目录 -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file://${hadoop.tmp.dir}/name</value>
    </property>

    <!-- DataNode数据存储目录 -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file://${hadoop.tmp.dir}/data</value>
    </property>

    <!-- JournalNode数据存储目录 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>${hadoop.tmp.dir}/jn</value>
    </property>

    <!-- 完全分布式集群名称 -->
    <property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>

    <!-- 集群中NameNode节点都有哪些 -->
    <property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2,nn3</value>
    </property>

    <!-- nn1的RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>hadoop102:8020</value>
    </property>

    <!-- nn2的RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>hadoop103:8020</value>
    </property>

    <!-- nn3的RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn3</name>
        <value>hadoop104:8020</value>
    </property>

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

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

    <!-- nn3的http通信地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn3</name>
        <value>hadoop104:9870</value>
    </property>

    <!-- 指定NameNode元数据在JournalNode上的存放位置 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
    </property>

    <!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>

    <!-- 使用隔离机制时需要ssh无秘钥登录-->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/liaoyanxia/.ssh/id_rsa</value>
    </property>


    <!-- 访问代理类:client,mycluster,active配置失败自动切换实现方式-->
    <property>
          <name>dfs.client.failover.proxy.provider.mycluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

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

分配两个文件到其他节点

java 复制代码
xsync core-site.xml hdfs-site.xml

在每个节点的/etc/profilr.d下的my_env.sh文件中修改HADOOP_HOME:

/opt/module/hadoop-3.3.1改为/opt/ha/hadoop-3.3.1

然后source一下让环境变量生效:

java 复制代码
source my_env.sh

启动HDFS-HA集群:

java 复制代码
//在各个JournalNode节点上,输入以下命令启动journalnode服务
hdfs --daemon start journalnode

//在nn1上进行格式化并启动
hdfs namenode -format
hdfs --daemon start namenode

//在nn2、nn3上同步nn1的元数据信息
hdfs namenode -boostrapStandby

//启动nn2和nn3
hdfs --daemon start namenode

//启动datanode
hdfs --daemon start datanode

//关闭所有hdfs服务
sbin/stop-dfs.sh

//启动zookeeper集群
zk.sh start

//初始化HA在zookeeper中的状态
bin/hdfs zkfc -formatZK

//启动hdfs服务
start-dfs.sh

3、Yarn-HA

3.1 Yarn-HA工作机制

  Yarn核心进程有两个,分别是ResourceManager和NodeManager,NodeManager是每个节点有一个,如果某个节点挂了则资源会少一点,但ResourceManager挂了则会发生单点故障,整个集群就用不了了,及不能提交任何任务,所以需要配置Yarn-HA。

  Yarn-HA也以来于zookeeper集群,启动多个ResourceManager,谁先启动成功谁就到zookeeper注册为临时节点。后启动的也会去zookeeper上注册节点,创建时发现节点已经存在即指定转为standby,所有的standby节点以轮询的方式询问节点信息是否存在,一旦节点信息不存在则立马主机注册为新的节点为Active,即当一个Active的ResourceManager进程挂点之后,zookeeper中的临时节点会自动删除。

3.2 Yarn-HA集群配置

3.2.1 集群规划


核心问题

(1)如果当前Active rm挂了,其他Standby rm利用zk的临时节点上位;

(2)当前rm上有很多计算程序在等待运行,em会将当前所有计算机程序的状态存储在zk,其他em上位后会读取,任何接着跑。

3.2.2 配置Yarn-HA集群

配置yarn-site.xml,删除原有的内容,添加以下:

xml 复制代码
<property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <!--启用resourcemanager ha-->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
 
    <!--声明两台resourcemanager的地址-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>cluster-yarn1</value>
    </property>

    <!-- 指定resourcemanager的逻辑列表 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2,rm3</value>
    </property>

    <!--rm1的主机名-->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop102</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop103</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm3</name>
        <value>hadoop104</value>
    </property>

    <!--rm1的web端地址-->
    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>hadoop102:8088</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>hadoop103:8088</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address.rm3</name>
        <value>hadoop104:8088</value>
    </property>

    <!--rm1的内部通信地址-->
    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>hadoop102:8032</value>
    </property>

    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>hadoop103:8032</value>
    </property>

    <property>
        <name>yarn.resourcemanager.address.rm3</name>
        <value>hadoop104:8032</value>
    </property>

    <!--指定AM向rm1申请资源的地址-->
    <property>
        <name>yarn.resourcemanager.scheduler.address.rm1</name>
        <value>hadoop102:8030</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.address.rm2</name>
        <value>hadoop103:8030</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.address.rm3</name>
        <value>hadoop104:8030</value>
    </property>

    <!--指定供NM连接的地址-->
    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
        <value>hadoop102:8031</value>
    </property>

    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
        <value>hadoop103:8031</value>
    </property>

    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm3</name>
        <value>hadoop104:8031</value>
    </property>
 
    <!--指定zookeeper集群的地址--> 
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
    </property>

    <!--启用自动恢复--> 
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
 
    <!--指定resourcemanager的状态信息存储在zookeeper集群--> 
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>

    <!--环境变量的继承-->
    <property>
        <name>yarn.nodemanager.env-whilelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
java 复制代码
//分配到其他节点
xsync yarn-site.xml

//关闭hdfs
sbin/stop-all.sh

//开启hdfs
sbin/start-dfs.sh

//将nn1切换为Active状态
hdfs haadmin -transitionToActive nn1

//启动yarn
sbin/start-yarn.sh

//查看服务状态
bin/yarn 1rmadmin -getServiceState rm1
相关推荐
大大大大晴天35 分钟前
每天认识一个组件:数据治理Apache Atlas
大数据
数字新视界1 小时前
2026模块化机房选型指南:行业市场发展趋势、占有率与竞争梯队分析报告解析
大数据·人工智能·物联网·数据中心·微模块机房·模块化机房·冷通道
姜穆澜3 小时前
OneID 从 0 到 1 完整生产案例(四)
大数据
OsDepK3 小时前
项目快速Git至仓库(完整版)
大数据·git·elasticsearch·搜索引擎
合米AI SOP系统4 小时前
传统产线如何快速上马落地 AI 防错?合米科技 AI SOP 7天即可上线。
大数据·人工智能·科技
思录Echo4 小时前
什么决定具身智能的最终走向?多技术路线与落地现实辨析
大数据·人工智能
xiaohaiAIgeo4 小时前
【2026年】AI监控加行为分析守护实验室安全
大数据·人工智能·科普知识
林墨聊AIGC5 小时前
动漫AI视频创作工具在哪找到的?2026年最新动漫AI视频平台与软件指南
大数据·人工智能·ai作画·aigc·音视频
故七月6 小时前
告别 AI 时代品牌 “隐身”:万域智瞰 AI‑GEO,构建品牌大模型时代营销新基建
大数据·人工智能
数字孪生视频孪生8 小时前
三维实时重构异构底座 核工危化无感定位跨境轨迹一屏统揽
大数据·运维·人工智能·重构·架构