1)所谓HA(high available),即高可用(7*24小时不中断服务)。
2)实现高可用最关键的策略是消除单点故障。Hadoop HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
官网:http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.15.1/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html
Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。NameNode主要在以下两个方面影响HDFS集群
1)NameNode机器发生意外,如宕机,集群将无法使用。
2)NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。在出现故障时进行无感知的主备切换。
HDFS HA与之前的分布式集群对比, 应该进行以下改变:
1)元数据管理方式需要改变:
因为存在两个及以上个NN,内存中应该各自保存一份元数据。为了使Standby节点保持其状态与Active节点同步,需要将edits日志放在一个共享存储中进行管理(QJM和NFS两个主流实现,本文说的是QJM),两个节点都与一组称为JournalNodes(JN)的单独守护进程通信,edits日志会持久地记录到大多数这些JN中,Standby节点能从JN中读取edits日志,并将edits日志应用到自己的命名空间,进行“重演”。如果发生故障转移,Standby将确保在将自身升级为Active状态之前已读取JounalNodes的所有编辑内容。这可确保在发生故障转移之前完全同步命名空间状态。
因为edits日志必须写入大多数JN,必须至少有3个JournalNode守护进程,这将允许系统容忍单个机器的故障。为了实际增加系统可以容忍的失败次数,JN应配置为奇数个(即3,5,7等)。如果配置了N个 JournalNodes,系统最多可以容忍(N-1)/ 2个故障。
在故障转移时,应对旧的Active节点进行隔离(Fence),即同一时刻仅仅有一个NameNode对外提供服务,否则,命名空间状态将在两者之间快速分歧,存在数据丢失或其他不正确结果的风险,这个场景称为split-brain(脑裂)。为了防止脑裂, JN同一时间仅允许一个NN 写入。
为了提供快速故障转移,Standby节点还必须具有关于群集中block的位置的最新信息。为了实现这一点,DataNode应同时向两者发送块位置信息和心跳。
因为有多个NN,而NN谁是active谁是standby对于用户来说应该是无感知的,这就引入了nameservices的概念, 为HA取一个统一的名字,在访问集群时只需要通过该nameservices来访问,在执行操作的时候会从配置参数中随机找到一个NN来判断这个NN是否为active,是则继续执行命令,否则切换为另一个NN。
2)需要存在状态管理的功能模块
若仅满足以上的需求,即使Active节点发生故障,系统也不会自动触发从Active到Standby的故障转移。需要进行手动的故障转移。 手动故障转移显然不是我们所需要的解决方案。 为了实现自动故障转移,需要引入两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程。
Apache ZooKeeper是一种高可用性服务,用于维护少量协调数据,通知客户端该数据的更改以及监视客户端是否存在故障。自动故障转移的实现依赖于ZooKeeper来实现以下功能:
1) 故障检测 : 集群中的每个NameNode在ZooKeeper中维护了一个持久会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。
2) Active NameNode选举 ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果当前Active节点崩溃,则另一个节点可能从ZooKeeper获得特殊的排他锁以表明它成为下一个Active节点。
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锁,它将为自己获取该锁。如果成功,则它已经赢得了选举,并通过RPC将它的本地NameNode的状态置为active。必要时对先前的Active进行隔离(Fence),然后本地NameNode转换为活动状态。
HDFS HA架构图:
注: 1)DN同时向active和standby发送心跳和块报告
2)ACTIVE NN将操作记录写到自己的edit log ,同时将edit log写入JN集群。每个JN都会写。
3)STANDBY NN: 同时接收JN集群的日志(随机选个写入成功的JN节点读),重演edits log操作,使得自己的元数据和active nn节点保持一致。
4) 在激活新的Active NN之前,会对旧的Active NN进行隔离操作防止脑裂。(kill掉)
ResourceManager(RM)负责跟踪集群中的资源,以及调度应用程序。在Hadoop 2.4之前,ResourceManager是YARN集群中的单点故障。
YARN HA 的架构相对简单,不需要像HDFS那样运行单独的ZKFC守护进程,嵌入在RM中的ActiveStandbyElector替代了它的工作,该线程充当故障检测器和领导者选择器。 RM可以通过ActiveStandbyElector来决定哪个RM应该是Active。当Active关闭或无响应时,另一个RM自动被选为Active。
在HDFS HA中, DN会同时向Active 和 Standby NN发送块报告和心跳。 但是在YARN HA中, NM只需要与Active RM做交互。
以上两个改变主要是因为,YARN是负责作业资源调度的,而HDFS是负责存储数据的,数据不能丢,作业可以挂, 所以YARN对于自动故障转移和作业资源的备份的要求不是特别严格。
以下是YARN HA的架构图:
RM Active通过RMStateStore维护状态信息, RMStateStore存储在zk的/rmstore目录下。RM启动的时候会向ZK的/rmstore目录写lock文件,写成功就为active,否则standby,ActiveStandbyElector会一直监控这个lock文件是否存在。
当active RM挂了,另外一个standby RM通过ActiveStandbyElector选举成功为active,会从/rmstore读取相应的作业信息。重新构建作业的内存信息,启动内部的服务。并开始接收NM的心跳,构建集群的资源信息,并且接收客户端的作业提交请求。