文章大纲:

在 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 的特点
下面的选举机制会进一步阐述前两个特点。
1.2Zookeeper 的节点类型
Zookeeper 的目录结构跟 HDFS 类似,整体上可看作一棵树,每个节点称作zNode,每个 zNode 可存储1MB数据,并可通过其路径唯一标识。

图1-2-1:Zookeeper 目录结构
zNode 的类型分为四类:

图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-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 三个组件:
主备切换的具体工作方式:

图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 类似:

图3-1-1:YARN HA 架构图
3.2 YARN HA 与 HDFS HA 的区别
YARN HA 尽管实现方式上与 HDFS HA 类似,但也存在以下的区别: