Hadoop HA 完全分布式工作机制

2022-01-07 17:04:39 浏览数 (1)

文章大纲:

在 Hadoop 1.x 版本中,是没有 HA 实现方式的,它只有可以看做是冷备份的 SecondaryNameNode 来起到备份作用,因为 2NN 能够协助 NameNode 做一些检查点的工作,能同步磁盘镜像(FSImage)和日志(EditLog). 当 NN 挂掉,2NN 是没有办法立即启动起来继续为集群服务的,需要用手工的方式启动 2NN,这显然会产生服务中断,对业务连续性产生较大影响。

因此 Hadoop 2.x 版本中开始引入 HA 的热备份机制,包括 HDFS(NameNode) HA 和 YARN(ResourceManager) HA. 当主 NN 挂掉后,备 NN 会立即启动进行接管,从而为集群提供不间断的服务,保证集群对外没有任何宕机情况。而 DataNode 和 NodeManager 本身就是被设计为集群模式的,所以不用对他们引入特殊的 HA 机制处理。

1 Zookeeper

Zookeeper 是基于观察者模式设计的分布式管理协作开源框架,为分布式应用提供协调服务,负责接受观察者注册,并通知注册的观察者数据状态的变化。简单来说,就是文件系统及通知机制的组合。

图1-1-1:Zookeeper 工作机制

Zookeeper 集群可以用来保证 Hadoop 集群的高可用,其原理是(HDFS HA 中会作详细讲解):

Hadoop 集群中有两个 NameNode 服务,两个 NN 都会定时给 Zookeeper 发送心跳,告诉 Zookeeper 我还活着,可以提供服务,某一个时间只有一个 NN 是Active 状态,另外一个则是Standby 状态;一旦 Zookeeper 检测不到 Active NN 发送的心跳,就会切换到 Standby 状态的 NN 上,将其设置为 Active 状态。所以集群中总有一个可用的 NN,达到 NN 高可用目的。

1.1 Zookeeper 的特点

  • Zookeeper 是由一个 Leader 和多个 Followers 组成的集群
  • 只要有半数以上节点存活,Zookeeper 即可正常提供服务
  • 集群中的每个 Server 保存一份相同的数据副本,以保证全局数据的一致性
  • 来自同一个 Client 的更新请求按其发送顺序依次执行
  • 数据更新具有原子性,一次数据更新要么成功,要么失败
  • 数据具有实时性,在一定时间范围内,Client 能读到最新的数据

下面的选举机制会进一步阐述前两个特点。

1.2Zookeeper 的节点类型

Zookeeper 的目录结构跟 HDFS 类似,整体上可看作一棵树,每个节点称作zNode,每个 zNode 可存储1MB数据,并可通过其路径唯一标识。

图1-2-1:Zookeeper 目录结构

zNode 的类型分为四类:

  • 持久化节点(Persistent):节点创建后一直存在,不会因为创建该节点的 Client 与 Zookeeper 的会话失效而消失。
  • 持久化顺序编号节点(Persistent_sequential):这类节点的基本特性和持久化节点是一致的,不同的是,Zookeeper 的每个父节点会为他的第一级子节点维护一份时序,记录每个子节点创建的先后顺序,顺序号是一个单调递增的计数器。
  • 临时节点(Ephemeral):节点创建后,其生命周期和 Client 会话绑定,若创建该节点的 Client 与 Zookeeper 的会话失效,这个节点就会自动被清除掉。此类节点下不能创建子节点。
  • 临时顺序编号节点(Ephemeral_sequential):这类节点的基本特性和临时节点是一致的,不同的是,此类节点会被父节点维护一份时序,创建的节点带顺序编号。

图1-2-2:Zookeeper 节点类型

1.3 Zookeeper 的选举机制

Zookeeper 集群除了能让 Hadoop 高可用外,其自身也有一套 HA 机制。

Zookeeper 集群机器中会有一个 Leader 和多个 Followers 的角色。因为集群中的 Leader 角色只有一个,因此就会存在单点故障的隐患,而 Zookeeper 的选举机制就是用来解决单点故障隐患,以实现高可用的。

Leader 角色由哪台机器担任不是固定的,而是由内部的选举机制临时产生的。选举的流程是:集群中处于启动的任意一台机器发现集群中没有 Leader 时,就会推荐自己为 Leader,其他机器来同意,当超过半数的机器同意它为 Leader 时,选举结束。

图1-3-1:Zookeeper 选举机制

由此可见,Zookeeper 集群中只要有半数以上的机器存活,集群即可用。因此,Zookeeper 集群适合安装奇数台机器,这样就算当 Leader 机器宕机后,也能很快选举出新的 Leader,保证了 Zookeeper 集群本身的高可用,同时也能避免资源浪费。

1.4 Zookeeper 的数据读写流程

Zookeeper 的数据写入 HA 流程:

  1. Client 向 Zookeeper 请求写入数据时,要先写入 Leader,若收到请求的机器不是 Leader,则写入数据的请求会转发给 Leader
  2. Leader 同意写入后,会将请求广播给各个机器,通知 Followers 写入,各机器写入成功后会通知 Leader
  3. 当 Leader 收到大多数(半数以上)机器写入数据成功,则认为数据写入成功,进而通知接收到请求的机器,因此就算有部分机器宕机,也不会影响数据写入
  4. 接收请求的机器会进一步通知发出请求的 Client 数据写入成功

图1-4-1:Zookeeper 数据写入流程

Zookeeper 的读取数据 HA 流程:

Client 向 Zookeeper 请求读取数据时,因为 Zookeeper 的全局数据一致性特点,无需通知 Leader,可以直接从任意一台机器上读取数据,因此就算有部分机器宕机,也不会影响数据读取。

2 HDFS HA

HDFS 是单 NameNode 的 Hadoop 非 HA 部署的缺陷在于会存在单点故障问题,若 NameNode 不可用,则会导致整个 HDFS 文件系统不可用。所以需要设计高可用的 HDFS(Hadoop HA)来解决 NameNode 单点故障的问题。

2.1 HDFS HA 架构

在 Hadoop 2.x 版本中,HDFS 架构解决了单点故障问题,其方式是在 HDFS 集群中引入多 NameNode 节点架构,同时借助共享存储系统来进行元数据的同步,并使用 Zookeeper 集群进行 NameNode 之间的协作。因此HDFS 的 HA 机制主要是依靠依赖于 QJM 共享存储组件的元数据同步和依赖于 Zookeeper 和 ZKFC 的主备选举机制。

图2-1-1:HDFS HA 架构图

2.2 Quorum Journal Manager(QJM)

元数据的同步主要是要保证主备 NameNode 的元数据是保持一致的,即保证磁盘镜像(FSImage)和日志(EditLog)在备 NN 上也是完整的,而元数据的同步很大程度取决于 EditLog 的同步,而这步的关键就是共享存储系统。

共享存储系统的一般类型有:Shared NAS NFS、BookKeeper、BackupNode 和 Quorum Journal Manager(QJM),目前用得较多的是 QJM 共享存储组件,通过搭建奇数台 JournalNode 实现主备 NameNode 之间的元数据信息同步。

QJM 全称是 Quorum Journal Manager, 由 JournalNode(JN)组成,一般会搭建奇数台机器,以实现 JN 的高可用。每个 JN 对外有一个简易的 RPC 接口,以供 NN 读写 EditLog 到 JN 本地磁盘。当写 EditLog 时,Active NN 会同时向所有 JN 并行写文件,只要有半数以上机器写成功则认为此次写操作成功(与 Zookeeper 的数据写入类似)。

Standby NN 不对外提供元数据的访问,它从 Active NN 上拷贝 FSImage 文件,从 JN 上拷贝 EditLog 文件,然后合并 FSImage 和 EditLog 文件,相当于 2NN 的作用。最终目的是保证 Standby NN 的元数据信息和 Active NN 的元数据信息一致,以实现热备份。

图2-2-1:QJM 内部实现框架

2.3 主备故障自动切换机制

要完成 HA,除了元数据同步外,还得有一个完备的主备故障自动切换机制,这个机制就是依赖于 Zookeeper 集群的主备选举机制,而整个切换的过程由 ZKFC 来进行控制。

ZKFC 是自动故障转移中的一个组件,是 Zookeeper 的客户端,每个运行 NameNode 的主机上都会启动一个 ZKFC 进程。ZKFC 可以监视和管理 NameNode 的状态,并把 NN 的状态信息汇报给 Zookeeper 集群。

ZKFC 可分为 HealthMonitor、ZKFailoverController 和 ActiveStandbyElector 三个组件:

  • ZKFailoverController: HealthMontior 和 ActiveStandbyElector 的母体,执行具体的切换操作
  • HealthMonitor: 监控 NameNode 健康状态,若状态异常会触发回调 ZKFailoverController 进行自动主备切换
  • ActiveStandbyElector: 通知 Zookeeper 执行主备选举,若 Zookeeper 完成变更,会回调 ZKFailoverController 相应方法进行主备状态切换

主备切换的具体工作方式:

  1. ZKFC 的 HealthMonitor 组件会负责监控 NameNode 节点的状态,并将监控状态返回 FailoverController 组件,通过 Heartbeat 将监控状态保存在 Zookeeper 中的一个 zNode(其节点类型为临时节点)中,并保持一个特殊的 zNode 锁。
  2. 当 Active NN 出现故障后,Zookeeper 会通过 Active ZKFC 的 FailoverController 感知,而由于 zNode 是临时节点,会话失效,节点就会被删除。
  3. 此时 ActiveStandbyElector 组件会通知 Zookeeper 进行主备选举,选举方式:若 Standby NN 是健康的,且 Standby ZKFC 发现没有其它的节点当前持有 zNode 锁,它将为自己获取该锁;如果成功,则它赢得选举。选举结果返回 FailoverController 组件。
  4. Standby ZKFC 的 FailoverController 通知 Zookeeper 将自己的 NN 切换为 Active 状态,并修改 zNode 上的数据。

图2-3-1:HDFS HA 主备切换工作方式

防脑裂机制:

当 HDFS 中同一时刻出现两个及以上的 Active NameNode 即出现脑裂(Brain Split)。

防止脑裂出现的方法是,在故障切换期间,Zookeeper 会让出现故障的 Active NN 通过 FailoverController 通知 Standby ZKFC,强行杀掉 Active NN 的进程以防止脑裂。若此举失效,Standby ZKFC 会调用用户自定义的程序脚本结束进程。

图2-3-2:HDFS HA 防脑裂机制

3 YARN HA

Hadoop 2.4 版本之后,YARN 也引入了 HA 的机制,以解决 ResourceManager 的单点故障问题,实现 YARN 的高可用性。

3.1 YARN HA 架构

YARN 的 ResouceManager 记录着当前集群的资源分配情况和 JOB 的运行调度状态,YRAN HA 利用 Zookeeper 来存储这些信息,并实现 RM 的主备故障自动切换。

YARN 主备切换的工作方式与 HDFS 类似:

  1. ResourceManager 启动后会向 Zookeeper 的目录写一个锁文件,若写成功则成为 Active RM,否则成为 Standby RM.
  2. Active RM 会向 Zookeeper 的 RMStateStore(位于/rmstore 下)写入资源分配及 JOB 运行调度状态等信息。
  3. ZKFC 会负责监控 ResourceManager 节点的状态,并将监控状态汇报 Zookeeper.
  4. 当 Active RM 出现故障后,ZKFC 会通知 Zookeeper 进行选举,并让 MasterHADaemon 停止 RM 的服务。若 Standby RM 是健康的,并发现锁文件缺失,它会尝试去创建锁文件,成功则赢得选举成为 Active RM.
  5. Standby ZKFC 通知 Zookeeper 将自己的 RM 切换为 Active 状态,并让 MasterHADaemon 启动 RM 的服务。
  6. 切换为 Active 状态的 RM 会从 Zookeeper 的/rmstore 目录读取相应的作业信息,并重构作业的内存信息,然后启动内部服务,开始接收 NodeManager 的心跳,构建集群资源的信息,并接收客户端的提交作业的请求等。

图3-1-1:YARN HA 架构图

3.2 YARN HA 与 HDFS HA 的区别

YARN HA 尽管实现方式上与 HDFS HA 类似,但也存在以下的区别:

  • HDFS HA 中,ZKFC 是一个独立守护的进程;YARN HA 中,ZKFC 是 RM 进程中的一个线程。
  • HDFS HA 由独立中间件的数据集群来维护;YARN HA 的资源分配及 JOB 运行调度信息维护在 Zookeeper 中。
  • HDFS 中的 DataNode 会向两个 NameNode 同时发送心跳;YARN 中 NodeManager 只会向 Active ResourceManager 上报资源。

0 人点赞