[INFRA] EMR集群启用HA高可用架构和配置分析

请注意本文部分内容经过AI辅助生成,虽然经过笔者检查但是并不保证内容的正确性,请自行判断准确性,本文对相关后果不承担责任

本次测试基于 EMR 7.12.0 HA 集群实际配置,在创建集群时配置如下external metastore并开启HA

json 复制代码
[
  {
    "Classification": "hive-site",
    "Properties": {
      "javax.jdo.option.ConnectionURL": "jdbc:mysql://172.31.14.46:3306/hive_metastore?createDatabaseIfNotExist=true",
      "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
      "javax.jdo.option.ConnectionUserName": "hive",
      "javax.jdo.option.ConnectionPassword": "hive"
    }
  }
]

EMR HA 集群通过部署 3 个 Master 节点,为 HDFS、YARN、HBase、Hive 等核心组件提供高可用能力。当任一 Master 节点故障时,服务可自动切换到其他节点,避免单点故障导致集群不可用。

节点拓扑

角色 实例类型 数量
Master m5.xlarge 3
Core m5.xlarge 2
Task c5.xlarge 1

3 个 Master 节点信息:

节点 私有 IP 私有 DNS
Master 1 192.168.31.118 ip-192-168-31-118.cn-north-1.compute.internal
Master 2 192.168.18.219 ip-192-168-18-219.cn-north-1.compute.internal
Master 3 192.168.17.6 ip-192-168-17-6.cn-north-1.compute.internal

HA 组件角色分布

各组件的 Active 角色分散在不同节点上,避免单节点承载所有 Active 服务:

组件 Active 节点 Standby/Backup 节点
HDFS NameNode 192.168.31.118 (nn1) 192.168.18.219 (nn2), 192.168.17.6 (nn3)
YARN ResourceManager 192.168.18.219 (rm2) 192.168.31.118 (rm1), 192.168.17.6 (rm3)
HBase Master 192.168.31.118 192.168.18.219, 192.168.17.6
ZooKeeper 192.168.18.219 (leader) 192.168.31.118 (follower), 192.168.17.6 (follower)
Hive Metastore 3 节点均运行(Active-Active) ---
HiveServer2 3 节点均运行(Active-Active) ---

HA 架构总览

组件依赖关系

复制代码
                        ┌─────────────────────────┐
                        │   ZooKeeper (3节点集群)    │
                        │   HA 架构的选举基础        │
                        └──────┬──────┬──────┬─────┘
                               │      │      │
                    ┌──────────┘      │      └──────────┐
                    ▼                 ▼                  ▼
              ┌───────────┐   ┌─────────────┐   ┌─────────────┐
              │   ZKFC    │   │    YARN RM   │   │ HBase Master│
              │ NN 选举    │   │  内嵌选举     │   │  ZK 选举    │
              └─────┬─────┘   └─────────────┘   └─────────────┘
                    ▼
              ┌───────────┐
              │ NameNode  │
              │ HA 切换    │
              └─────┬─────┘
                    │
              ┌─────▼─────┐
              │JournalNode│
              │ EditLog    │
              │ 同步(3节点) │
              └───────────┘

External MySQL (172.31.14.46:3306)
└── Hive Metastore 元数据存储(3 个 Metastore 实例共享)

各组件 HA 模式对比

组件 HA 模式 选举/协调方式 故障转移
HDFS NameNode Active-Standby (1+2) ZKFC + ZooKeeper 自动
YARN ResourceManager Active-Standby (1+2) 内嵌 ZooKeeper 选举 自动
HBase Master Active-Backup (1+2) ZooKeeper 自动
ZooKeeper Leader-Follower (1+2) ZAB 协议内部选举 自动
Hive Metastore Active-Active (3) 无需选举,多实例并行 客户端重连
HiveServer2 Active-Active (3) 无需选举,多实例并行 客户端重连

HDFS NameNode HA

HDFS NameNode HA 是整个 HA 架构中最复杂的部分,涉及 ZKFC、JournalNode、Fencing 等多个机制协同工作。

配置详情

/etc/hadoop/conf/hdfs-site.xml 关键配置:

xml 复制代码
<!-- 逻辑名称 -->
<property>
    <name>dfs.nameservices</name>
    <value>ha-nn-uri</value>
</property>

<!-- 3 个 NameNode -->
<property>
    <name>dfs.ha.namenodes.ha-nn-uri</name>
    <value>nn1,nn2,nn3</value>
</property>

<!-- 各 NameNode RPC 地址 -->
<property>
    <name>dfs.namenode.rpc-address.ha-nn-uri.nn1</name>
    <value>ip-192-168-31-118.cn-north-1.compute.internal:8020</value>
</property>
<property>
    <name>dfs.namenode.rpc-address.ha-nn-uri.nn2</name>
    <value>ip-192-168-18-219.cn-north-1.compute.internal:8020</value>
</property>
<property>
    <name>dfs.namenode.rpc-address.ha-nn-uri.nn3</name>
    <value>ip-192-168-17-6.cn-north-1.compute.internal:8020</value>
</property>

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

客户端使用逻辑名称 hdfs://ha-nn-uri/ 访问 HDFS,通过 ConfiguredFailoverProxyProvider 自动发现并连接 Active NameNode,无需关心具体哪个节点是 Active。

ZKFC(ZooKeeper Failover Controller)

ZKFC 是 Hadoop 原生组件,属于 hadoop-hdfs 模块(org.apache.hadoop.hdfs.tools.DFSZKFailoverController),在 Hadoop 2.0 引入 HDFS HA 时一起加入。每个 NameNode 旁边运行一个 ZKFC 进程,负责三件事:

  1. 健康监控 --- 通过 HealthMonitor 线程定期调用 NameNode 的 monitorHealth() RPC,判断 NameNode 是否正常
  2. ZooKeeper 会话管理 --- 在 ZooKeeper 中维护临时节点(ephemeral znode ActiveStandbyElectorLock),持有锁的 ZKFC 对应的 NameNode 为 Active
  3. 触发故障转移 --- 检测到 Active NameNode 不健康时,触发自动切换

注意:只有 HDFS NameNode 使用 ZKFC。YARN ResourceManager 的故障转移是内嵌在 RM 进程里的(automatic-failover.embedded=true),不需要额外的 ZKFC 进程。

JournalNode

JournalNode 负责在 Active 和 Standby NameNode 之间同步 EditLog(编辑日志)。3 个 Master 节点各运行一个 JournalNode。

HDFS 元数据由两部分组成:

  • FsImage --- 某个时间点的完整命名空间快照
  • EditLog --- 快照之后的所有变更操作(创建文件、删除目录、修改权限等)

工作方式:

复制代码
客户端写操作 → Active NameNode
                  ↓ 并行写 EditLog
              JournalNode 集群 (3节点,Quorum 多数派写入,2/3 成功即可)
                  ↑ 持续读 EditLog
              Standby NameNode (回放到内存,保持状态同步)

为什么不让 Active 直接把 EditLog 发给 Standby?因为如果 Active 挂了,正在传输的 EditLog 可能丢失。JournalNode 作为独立的第三方存储,即使 Active 挂了,已写入的 EditLog 不会丢。Quorum 机制保证即使一个 JournalNode 挂了,数据仍然完整。

JournalNode 没有主从之分,所有节点完全对等:

对比 ZooKeeper JournalNode
角色 Leader / Follower(有主从) 全对等,无主从
写入方式 写请求必须经过 Leader 转发 各节点独立接受写入
节点间通信 Leader 同步到 Follower 节点之间不互相通信
一致性保证 Leader 负责排序 NameNode 侧 Quorum 写入 + epoch number
节点故障 需要重新选举 Leader 无需选举,多数派存活即可

故障转移完整流程

当 Active NameNode 发生故障时,自动切换流程如下:

复制代码
1. 旧 Active NN 故障
      ↓
2. 旧 ZKFC 检测到 monitorHealth() 失败
      ↓
3. 释放 ZK 锁(或 ZKFC 也挂了则 session 超时自动释放 ephemeral znode)
      ↓
4. Standby ZKFC 竞争创建 /hadoop-ha/ha-nn-uri/ActiveStandbyElectorLock
   (ZooKeeper 保证只有一个 ZKFC 创建成功,赢得选举)
      ↓
5. Fencing 隔离旧 Active(sshfence kill 旧 NN 进程,防止脑裂)
   (如果 fencing 失败,不会继续提升,宁可无 Active 也不允许双 Active)
      ↓
6. 调用 transitionToActive() RPC 提升 Standby 为新 Active
      ↓
7. 新 Active 从 JournalNode 同步完所有未回放的 EditLog
      ↓
8. 开始接受客户端读写请求,写新的 EditLog 到 JournalNode

其中 Fencing 是关键步骤,保证任何时刻最多只有一个 Active NameNode,避免脑裂(split-brain)导致数据不一致。

YARN ResourceManager HA

配置详情

/etc/hadoop/conf/yarn-site.xml 关键配置:

xml 复制代码
<property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
</property>
<property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>ha-rm-uri</value>
</property>
<property>
    <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
    <value>true</value>
</property>
<property>
    <name>yarn.resourcemanager.ha.automatic-failover.embedded</name>
    <value>true</value>
</property>
<property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2,rm3</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>ip-192-168-31-118.cn-north-1.compute.internal</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>ip-192-168-18-219.cn-north-1.compute.internal</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm3</name>
    <value>ip-192-168-17-6.cn-north-1.compute.internal</value>
</property>

HA 机制

  • 3 个 ResourceManager:1 Active + 2 Standby
  • 故障转移内嵌在 RM 进程中(automatic-failover.embedded=true),基于 ZooKeeper 选举,不需要像 NameNode 那样额外运行 ZKFC 进程
  • 使用 ha-rm-uri 作为集群逻辑名称

内嵌选举(Embedded Failover)

YARN RM 的故障转移选举逻辑直接写在 RM 进程代码里(automatic-failover.embedded=true),不需要像 HDFS NameNode 那样额外启动独立的 ZKFC 进程:

复制代码
HDFS NameNode --- 外部选举(两个独立进程):
  NameNode 进程(只管 HDFS 服务)
    +
  ZKFC 进程(独立进程,负责健康检查 + ZK 选举 + 故障转移)

YARN ResourceManager --- 内嵌选举(单进程):
  ResourceManager 进程(YARN 服务 + 健康检查 + ZK 选举 + 故障转移,全在一个进程里)

RM 启动时自己去 ZooKeeper 抢锁,抢到就是 Active,没抢到就是 Standby。Active RM 挂了,ZK session 超时,其他 Standby RM 自动竞争成为新 Active。

设计不同是历史原因,HDFS NameNode HA 先实现,选择了外部 ZKFC 保持 NameNode 代码简洁;后来 YARN RM HA 实现时,把选举逻辑直接嵌入 RM 进程内部。功能上没有区别,都是通过 ZooKeeper 做选举,只是代码放的位置不同。

ZooKeeper 集群

3 个 Master 节点各运行一个 ZooKeeper 实例,组成 3 节点集群:

节点 角色
192.168.31.118 follower
192.168.18.219 leader
192.168.17.6 follower

Leader-Follower 模式

ZooKeeper 采用 Leader-Follower 模式,不是传统的主从复制:

  • Leader --- 处理所有写请求,负责将写操作广播给 Follower 并确保多数派确认后才提交
  • Follower --- 可以直接处理读请求;收到写请求时转发给 Leader

Follower 不是被动复制的"从"节点,它们主动参与写入投票,也能独立处理读请求。只是写操作的协调权集中在 Leader 上。

与 HDFS NameNode Active-Standby 的区别:

对比 HDFS NameNode ZooKeeper
模式 Active-Standby Leader-Follower
Standby/Follower 能否服务 不能,Standby 不接受客户端请求 能,Follower 可以处理读请求
写入 只有 Active 写 写请求都经过 Leader,但 Follower 参与确认
选举 由外部 ZKFC 触发 Leader 故障时 Follower 通过 ZAB 协议自动选举

在 HA 架构中的角色

ZooKeeper 是整个 HA 架构的选举基础,负责:

  • HDFS NameNode 的 Active 选举(通过 ZKFC)
  • YARN ResourceManager 的 Active 选举(内嵌)
  • HBase Master 的 Active 选举
  • HBase RegionServer 的注册和监控

3 节点集群容忍 1 个节点故障(多数派 = 2)。Leader 挂了,剩余 Follower 通过 ZAB(ZooKeeper Atomic Broadcast)协议自动选出新 Leader,不需要外部组件介入。

HBase HA

配置详情

/etc/hbase/conf/hbase-site.xml 关键配置:

xml 复制代码
<property>
    <name>hbase.zookeeper.quorum</name>
    <value>ip-192-168-31-118...,ip-192-168-18-219...,ip-192-168-17-6...</value>
</property>
<property>
    <name>hbase.rootdir</name>
    <value>hdfs://ha-nn-uri/user/hbase</value>
</property>

HA 机制

  • 1 Active Master + 2 Backup Masters,通过 ZooKeeper 选举
  • Active Master 负责 Region 分配和负载均衡
  • hbase.rootdir 使用 HDFS HA 逻辑名称 ha-nn-uri,不绑定单个 NameNode
  • 集群状态:1 active master, 2 backup masters, 2 servers, 0 dead, 1.0000 average load

Hive HA

Hive 的 HA 模式与其他组件不同,采用多实例并行运行:

服务 192.168.31.118 192.168.18.219 192.168.17.6
hive-hcatalog-server (Metastore) ✅ running ✅ running ✅ running
hive-server2 (HiveServer2) ✅ running ✅ running ✅ running
  • 3 个 Metastore 实例都可以接受请求,共享同一个外部 MySQL 数据库
  • 3 个 HiveServer2 实例都可以接受客户端连接
  • 不需要选举,任一实例故障时客户端重连到其他实例即可

与非 HA 集群的对比

对比项 非 HA 集群 HA 集群
Master 节点数 1 3
HDFS NameNode 单点 1 Active + 2 Standby,自动故障转移
YARN ResourceManager 单点 1 Active + 2 Standby,自动故障转移
HBase Master 单点 1 Active + 2 Backup
ZooKeeper 单节点 3 节点集群
Hive Metastore 单实例 3 实例 Active-Active
HiveServer2 单实例 3 实例 Active-Active
JournalNode 3 节点(EditLog 同步)
ZKFC 3 节点(NameNode 故障转移控制)
终止保护 默认关闭 默认开启
Master 放置策略 SPREAD(分散到不同硬件)

HA 状态检查命令

bash 复制代码
# HDFS NameNode 状态
sudo -u hdfs hdfs haadmin -getAllServiceState

# YARN ResourceManager 状态
yarn rmadmin -getAllServiceState

# ZooKeeper 角色
echo srvr | nc localhost 2181 | grep Mode

# HBase Master 状态
echo "status" | sudo -u hbase hbase shell

# ZKFC 服务状态
sudo systemctl status hadoop-hdfs-zkfc

# JournalNode 服务状态
sudo systemctl status hadoop-hdfs-journalnode

# Hive Metastore 服务状态
sudo systemctl status hive-hcatalog-server

# HiveServer2 服务状态
sudo systemctl status hive-server2
相关推荐
亚马逊云开发者2 小时前
S3 桶名不用再抢了:Account Regional Namespaces 来了
aws
zhojiew12 小时前
[INFRA] EMR集群LogPusher组件功能和运行原理分析
aws·emr·bigdata
zhojiew13 小时前
[INFRA] EMR集群CWagent组件功能和运行原理分析
aws·emr·bigdata
亚马逊云开发者19 小时前
MCP Server 终于能"记住"用户了:AgentCore 有状态会话实战
aws
zhojiew1 天前
[INFRA] EMR集群MetricsCollector组件功能和运行原理分析
aws·emr·bigdata
zhojiew1 天前
[INFRA] EMR集群Instance Controller组件功能和运行原理分析
aws·emr·bigdata
亚马逊云开发者2 天前
🔥 20 行代码搞定 AI Agent!查天气、算数学、读文档全包了
aws
亚马逊云开发者2 天前
被线上故障电话叫醒后,我花一下午搭了套零人工告警系统
aws
李白你好2 天前
云安全渗透测试框架 - 支持 AWS、Azure、GCP、阿里云、腾讯云、华为云的综合渗透测试工具和指南
阿里云·azure·aws