基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

讲讲YARN ResourceManager 的 HA(高可用)实现原理和架构

知识点图片

YARN ResourceManager (RM) 作为 Hadoop 集群的资源管理和任务调度的“大脑”,在早期版本中是单点故障(SPOF)。从 Hadoop 2.4 版本开始,YARN 引入了 ResourceManager HA(高可用)机制。

YARN RM HA 的核心思想是通过 Active/Standby(主备)模式 运行多个 ResourceManager,并借助 ZooKeeper 进行领导者选举和状态同步。

以下是 YARN ResourceManager HA 的架构和实现原理的深度解析:


一、 YARN RM HA 架构图解

在一个典型的 RM HA 架构中,主要包含以下几个核心组件:

  1. ResourceManager (Active):当前负责处理客户端请求、接收 NodeManager 汇报、进行资源分配和调度的 RM。
  2. ResourceManager (Standby):备用 RM,处于休眠状态。它不处理任何实际业务,只是时刻准备着在 Active RM 挂掉时接管工作。
  3. ZooKeeper 集群:负责分布式锁的提供(Leader Election)以及状态存储(RMStateStore)。
  4. Embedded ZKFC (ZooKeeper Failover Controller)内嵌在 RM 进程中的故障转移控制器,负责与 ZK 交互,监控 RM 健康状态并参与选举。(注:与 HDFS NameNode HA 独立的 ZKFC 进程不同,YARN 的 ZKFC 作为一个线程运行在 RM 内部)。
  5. RMStateStore (状态存储):用于持久化存储当前 RM 的核心元数据和应用程序状态,通常使用 ZooKeeper 充当。

二、 核心实现原理

YARN RM HA 的实现依赖于以下五个核心机制:

1. 状态持久化与恢复机制 (RMStateStore)

如果 Active RM 宕机,Standby RM 接管后需要知道集群中正在运行什么任务。因此,Active RM 会将关键状态不断写入外部存储(RMStateStore)。

  • 存储哪些数据:应用程的提交信息(Application ID、提交者等)、应用程序的运行状态(AppAttempt)、安全秘钥(Delegation Tokens)等。
  • 不存储哪些数据不存储各个节点的资源使用情况(Container 状态)。因为当 Standby RM 切换为 Active 后,各个 NodeManager 会重新向新的 Active RM 发送心跳,新的 RM 会通过这些心跳动态重建集群资源视图。这种设计大大减轻了持久化存储的压力。
  • 存储介质:生产环境中强烈推荐使用 ZKRMStateStore(基于 ZooKeeper)。

2. 自动领导者选举 (Leader Election)

YARN 利用 ZooKeeper 的临时节点(Ephemeral Node)机制来实现选举:

  • 两个 RM 启动时,其内部的 ActiveStandbyElector(ZKFC 线程)都会尝试在 ZK 上创建一个名为 ActiveStandbyElectorLock 的临时节点。
  • ZooKeeper 保证只有一个 RM 能创建成功。创建成功的 RM 成为 Active,创建失败的 RM 成为 Standby
  • Standby RM 会在 ZK 上对该临时节点注册一个 Watcher(监听器)。

3. 故障自动转移 (Automatic Failover)

  • 当 Active RM 发生故障(如进程崩溃、机器断电)时,它与 ZK 的会话(Session)会超时断开。
  • ZK 自动删除 ActiveStandbyElectorLock 临时节点。
  • Standby RM 的 Watcher 收到节点被删除的通知,立即尝试去创建该节点。
  • 创建成功后,Standby RM 将自身状态切换为 Active

4. 脑裂防护机制 (Fencing 隔离)

“脑裂”(Split-Brain)是指两个 RM 同时认为自己是 Active,导致集群状态混乱。YARN 采用了非常巧妙的隔离机制:

  • HDFS 的做法:HDFS NameNode HA 通常使用 SSH 登录过去杀进程(Kill)的方式进行 Fencing。
  • YARN 的做法:YARN 依赖 ZooKeeper 的 ACL(访问控制列表) 来实现。
    • 只有当前的 Active RM 拥有修改 ZK 中 RMStateStore 目录的权限。
    • 如果发生了假死(例如旧的 Active RM 因为 JVM GC 暂停了很久,导致 ZK 认为它死了并把主节点交给了新 RM)。
    • 当旧的 Active RM 醒来,尝试向 RMStateStore 写入状态时,因为 ZK 的 ACL 权限已经在这个过程中被新 RM 抢占并重置,旧 RM 会收到一个 KeeperException.NoAuth 异常。
    • 旧 RM 捕获到该异常后,会意识到自己已经不是合法的 Active 了,会主动将自己降级为 Standby 或者直接退出进程,从而完美避免脑裂。

5. 客户端与 NodeManager 的透明重定向

  • 客户端 (Client) 和 AppMaster:在配置文件 yarn-site.xml 中,会同时配置 RM1 和 RM2 的地址。当客户端发起请求时,它会轮询(Round-Robin)列表中的 RM。如果连上的 RM 是 Standby,它会抛出 StandbyException,客户端捕获后会自动重试另一个 RM,直到找到 Active 为止。
  • NodeManager:同样配置了所有 RM 的地址。如果发现 Active RM 连接不上,会自动去连接另一个 RM 进行汇报。

三、 完整的故障切换流程 (Failover Workflow)

假设 RM1 是 Active,RM2 是 Standby。

  1. 正常运行:RM1 处理客户端请求,接收 NM 心跳,并将 Application 状态同步写入 ZK 的 RMStateStore。RM2 处于休眠等待状态。
  2. 灾难发生:RM1 所在的机器突然宕机。
  3. 锁释放:RM1 与 ZooKeeper 的 TCP 连接断开,Session 超时,ZK 上的临时锁节点被删除。
  4. 备机感知:RM2 内嵌的 ZKFC 监听到锁节点被删除的事件。
  5. 备机夺权:RM2 发起选举,成功在 ZK 上创建临时锁节点。
  6. 状态恢复 (Recovery)
    • RM2 成为新的 Active。
    • RM2 从 ZKRMStateStore 读取之前 RM1 存下的 Application 状态和安全凭证。
    • RM2 恢复这些 Application 的运行(比如重新拉起处于中间状态的 ApplicationMaster)。
  7. 资源重建:各个 NodeManager 发现 RM1 失联,轮询尝试连接 RM2。连接成功后,NM 把自己节点上的 Container 运行情况上报给 RM2,RM2 在内存中重建整个集群的资源分布图。
  8. 服务恢复:客户端重试连接到 RM2,集群业务无缝继续运行,用户几乎感知不到中断。

四、 总结

YARN ResourceManager HA 的设计十分轻量且优雅:

  1. 内嵌 ZKFC 减少了额外的进程管理负担。
  2. 分离状态存储与资源视图(只持久化应用状态,资源视图靠 NM 心跳重建),大大降低了高可用状态切换时的 I/O 开销,使得切换速度极快。
  3. 基于 ZK ACL 的 Fencing 机制,比传统的脚本 kill 方式更安全、更可靠。
00:00
00:00