转帖请注明本空间地址:http://blog.csdn.net/chenpingbupt
从evernote粘过来的格式还是乱了,文末附上格式良好的原文截图
本文基于cloudera-Hadoop-cdh-4.01版本进行分析
在这个特定版本支持HA的Hadoop内,FailoverController主要是通过一个独立于NN的进程来完成的,在这个版本内是通过zookeeper的功能来完成的,所以这个版本内的FailoverController也称为ZKFC。这部分代码主要存在于org.apache.hadoop.ha以及org.apache.hadoop.ha.protocolPB目录下。
在启动NN之前需要先将首先需要将zkfc启动后,如果是第一次启动还需要进行将zkfc进行初始化,初始化的目的主要是在zookeeper中创建必须的监控节点。
ZKFC的格式化方式为:sh bin/hdfs zkfc -formatZK和sh bin/hdfs start zkfc
以下对zkfc的工作流程进行详细分析:
执行zkfc的format或者start的时候,实际是使用org.apache.hadoop.hdfs.tools.DFSZKFailoverController来发起相应的操作,具体执行的是:
* 在ToolRunner.run()->tool.setConf(conf)内,首先读取conf文件,从 dfs.ha.namenode.id,dfs.nameservices或dfs.nameservice.id或自动的获取nnid和nsid。获取之后,将各个conf配置减去nsid和nnid这两个后缀重新set的老版本的配置项中。initializeGenericKeys和setGenericConf即完成这个事情。
执行bin/hdfs haadmin -DFSHAadmin -transitionToActive/Standby nn1时,将会把ActiveNN设置为nn1,具体的过程如下:
* DFSHAAdmin首先从conf文件中解析出nn1这个NamespaceID所指代的HAServiceTarget
检查参数中是否带有force,如果是不带force且设置了automatic-Failover,那么将不会进行后续操作,否则继续执行。
从rpc框架中获取到达HAServiceTarget大proxy,然后从在这个proxy上调用rpcProxy.transitionToActive( NULL_CONTROLLER , req)/rpcProxy.transitionToStandby(reqInfo);
目标NN接受该请求以后,再次检查这个请求的来源,合理性。以及执行用户的权限是否足够。
依据当前状态和请求状态,分两种情况处理:
Standby->Active首先准备从当前的standby状态中退出,执行的是namesystem.prepareToStopStandbyServices()->standbyCheckpointer .cancelAndPreventCheckpoints(), 这里主要是取消当前的正在进行的Checkpoint以及取消下一个预定执行的Checkpoint
然后执行准备进入Active状态,prepareToEnterState(),目前该操作未实现
接着执行退出Standby状态,context.stopStandbyServices()->namesystem .stopStandbyServices(),在这里会停止CheckpointerThread和EditLogTailerThread,关闭editLog。
在关闭Editlog的时候,如果当前状态是IN_SEGMENT首先会waitForSyncToFinish();然后endCurrentLogSegment( true ),最后journalSet .close()。
设置context的state,即:context.setState(s);
真正的进入Active状态,即:s.enterState(context),其实这里面就是启动ActiveService和TrashEmptier。Active->Standby过程大致相同
首先准备退出执行prepareToExitState,这个方法没有实际操作需要执行
然后准备进入执行prepareToEnterState(context),这个方法没有实际操作需要执行
退出Active状态,执行的是context.stopActiveServices(),这里主要完成stopTrashEmptier();,stopSecretManager(),leaseManager.stopMonitor(),dir.fsImage.editLog.close()以及dir.fsImage.updateLastAppliedTxIdFromWritten();设置context的state,即:context.setState(s);
真正进入Standby状态,执行context.startStandbyServices();主要完成的是dir.fsImage.editLog.initSharedJournalsForRead();editLogTailer .start();standbyCheckpointer .start();这几个线程的初始化。可以看到这几个过程不会判断当前NN的状态是否具备转换为ActiveNN的能力,如当前NN是否与老的ActiveNN的状态是否一致,等等。所以这个操作需要操作人在非常清楚目前各个NN的状态下进行方保无虞。
执行bin/hdfs haadmin -DFSHAadmin -failover [--forcefence] [--forceactive]
同理,首先解析fromNN和toNN这两个NamespaceID所指代的HAServiceTarget
判断当前是否这atuomaticHA,如果设置了,判断两个-force参数是否设置,如设置其中之一,便退出,因为HA已经包含这两者。否则继续执行
接下来的操作依据是否设置AutomaticHA,分两种情况进行:
1、设置了AutomaticHA,通过与toNode本地的ZKFC来协商进行一次Failover,具体如下:
1、执行HAAdmin.gracefulFailoverThroughZKFCs (toNode)
2、获取toNode的zkfcProxy,在该Proxy上调用proxy.gracefulFailover();
3、ZKFC-Server接受到该rpc请求之后,首先判断该操作的acl是否容许,如果容许,则继续进行操作。
4、检查本地NN的状态是否healthy,否则异常抛出。
5、检查老的ActiveNN是否即为本地NN,如果是,直接返回。
6、通知老的ActiveNN退出Active状态,即执行oldZkfc.cedeActive(timeout)->zkfc.cedeActive (millisToCede),这个过程需要在进一步分析一下:
1、zkfc接到rpc请求之后,首先判断ack权限是否足够
2、检查recheckElectability,看是否需要设定elector在一个时间段之后再次执行recheckElectability,或是立即joinElection/quitElection。
3、通知本地nn转移到Standby,执行rpcProxy.transitionToStandby (createReqInfo())。如果执行异常了,那么就需要fence了,影响到后续quitElection(needFence)。4、通知elector退出选举,执行elector.quitElection(needFence)->(如果需要fence则执行)tryDeleteOwnBreadCrumbNode->zkClient.close();
5、再次执行recheckElectability()确定何时应该再次参与选举。
7、等待本地的NN被正常的选举为ActiveNN,执行waitForActiveAttempt(timeout + 60000);这个过程通过ActiveStandbyElector的CallBack来完成,在CallBack被通知能够进行becomeActive()的时候,也调用NN.becomeActive()来进行状态转化。
2、在没有设置AutomaticHA的时候,首先初始化一个FailoverController fc = new FailoverController(getConf(), requestSource),然后用这个fc来完成Failover,即:fc.failover(fromNode, toNode, forceFence, forceActive);
手机扫一扫
移动阅读更方便
你可能感兴趣的文章