ZKFailoverController是NameNode机器上的一个独立进程,在启动时会创建HealthMonitor和ActiveStandbyElector两个内部组件,并向这两个组件注册相应的回调方法
HealthMonitor主要负责检测NameNode健康状态,若NameNode状态发生变化,则回调ZKFailoverController相应方法进行自动的主备选举
ActiveStandbyElector负责完成自动的主备选举,内部封装了Zookeeper的处理逻辑,一旦Zookeeper主备选举完成,则回调ZKFailoverController相应方法进行NameNode的主备状态切换
getServiceStatus
monitorHealth
transitionToActive
transitionToStandby
HealthMonitor在内部启动一个线程来循环调用NameNode的HAServiceProtocol接口的方法来检测NameNode的状态, 并将状态的变化通过回调的方式通知ZKFailoverController
HealthMonitor通过调用HAServiceProtocol接口的方法获取NameNode节点两类状态:健康状态和HA状态
利用Zookeeper的写一致性和临时节点机制完成主备选举
创建锁节点
主备选举的过程是尝试在Zookeeper的一个路径下创建临时节点ActiveStandbyElectorLock,Zookeeper的写一致性会保证只有一个ActiveStandbyElector创建成功,创建成功的ActiveStandbyElector对应的NameNode成为主NameNode,失败的成为备NameNode
注册Watcher监听
不管创建节点是否成功,ActiveStandbyElector都会向Zookeeper注册一个Watcher来监听这个节点的状态变化时间,主要是NodeDeleted事件
自动触发主备选举
如果Active NameNode对应的HealthMonitor检测到NameNode状态异常,ZKFailoverController会主动删除在Zookeeper上建立的临时节点
如果Active NameNode所在的机器整个宕掉,根据Zookeeper的临时节点特性,节点会被自动删除
处于Standby NameNode上的ActiveStandbyElector注册的监听器就会收到这个节点的NodeDeleted事件,再次进入创建节点流程,如果创建成功,这个处于Standby状态的NameNode就被选举为主NameNode
防止假死引发脑裂
ActiveStandbyElector在创建Zookeeper上的ActiveStandbyElectorLock节点从而成为Active NameNode后,会创建一个ActiveBreadCrumb持久节点,这个节点保存了这个Active NameNode的地址信息
Active NameNode的ActiveStandbyElector在正常状态下关闭Zookeeeper Session时,会一起删除这个持久节点
如果在异常状态下关闭Zookeeper Session,不会是删除这个持久节点,当另一个NameNode选主成功后,会注意到这个留下来的节点,回调ZKFailoverController的方法对旧的Active NameNode进行fencing隔离
对HealthMonitor状态变化的处理
HealthMonitor.State起主要作用
状态为健康时,当前的NameNode有资格参加主备选举,如果还未进行过主备选举,ZKFailoverController会调用ActiveStandbyElector的joinElection方法发起一次主备选举
状态为不健康或未响应,ZKFailoverController会调用ActiveStandbyElector的quitElection方法删除临时节点退出主备选举
HAServiceStatus起辅助作用
HAServiceStatus发生变化时,ZKFailoverController注册到HealthMonitor上的处理HAServiceStatus状态变化的回调函数会判断NameNode返回的HAServiceStatus和ZKFailoverController所期望的是否一致,如果不一致,ZKFailoverController会调用ActiveStandbyElector的quitElection方法删除临时节点退出主备选举
对ActiveStandbyElector主备选举状态变化的处理
ActiveStandbyElector选主成功,ActiveStandbyElector会回调ZKFailoverController的becomeActive方法,这个方法调用NameNode的HAServiceProtocol接口的transitiontoActive方法
ActiveStandbyElector选主失败,ActiveStandbyElector会回调ZKFailoverController的becomeStandby方法,这个方法调用NameNode的HAServiceProtocol接口的transitiontoStandby方法
ActiveStandbyElector选主成功后,发现上一个Active NameNode留下的ActiveBreadCrumb节点,ActiveStandbyElector会首先回调ZKFailoverController注册的fenceOldActive方法
基于QJM(Quorum Journal Manager)的共享存储系统用于保存EditLog,FSImage文件还是在NameNode的本地磁盘上
多个JournalNode节点组成集群,每个JournalNode保存同样的EditLog副本
Active NameNode首先把EditLog提交到JournalNode集群,然后Standby NameNode再从JournalNode集群定时同步EditLog
每次NameNode写EditLog时,除了向本地磁盘写入外,会并行地向JournalNode集群中的每个JournalNode发送写请求,只要大多数的JournalNode节点返回成功就认为想JournalNode集群写入成功
原文:https://www.cnblogs.com/lijiong/p/14415596.html