StandbyService of Standby NameNode------Checkpointer及EditLogTailer分析

17 篇文章 0 订阅
7 篇文章 0 订阅
转帖请注明本空间地址: http://blog.csdn.net/chenpingbupt  


NameNode上的service大致分为了三个类别,一个是ActiveService,一个是StandbyServcie,还有一个CommanService。其中ActiveNameNode会启动CommanService和ActiveService,而StandbyNameNode会启动CommanService和StandbyService。这里分析StandbyService的内容,其实StandbyService主要包括的是Checkpointer及EditLogTailer这两个特定后台线程。详细分析如下:

1、在StandbyNN最后启动的时候,会启动Standby类型的services,这包括:
1、EditLogTailer:dir.fsImage.editLog.initSharedJournalsForRead();-->editLogTailer = new EditLogTailer(this, conf);-->editLogTailer.start();
2、Checkpointer:standbyCheckpointer = new StandbyCheckpointer(conf, this);-->standbyCheckpointer.start();->CheckpointerThread.start();
2、首先分析EditLogTailer的所作所为
1、首先进行构造,在构造函数内,首先构建一个EditLogTailerThread(),然后从conf中获取各种时间配置。
2、然后启动EditLogTailerThread,开始执行其run()方法,内部调用doWork()。
3、首先判断上次进行logroll的时间距离现在是不是超过了一个周期,并且最后load的txid是否大于上次roll过的txid(即roll之后,tail是否去读过)。如如果两者都为True,则向nn发起一个LogRoll的请求triggerActiveLogRoll()->getActiveNodeProxy().rollEditLog(),下面详细分析以下在NameNodeRpcServer接收到rollEditLog的请求之后是如何响应的:
1、获取fsnamesystem的writeLock
2、检查操作种类在当前状态是否合法,ActiveNN支持任何操作,checkOperation(OperationCategory. JOURNAL)。
3、从EditLog中进行getEditLog().rollEditLog(),分为两个步骤:
1、首先进行endCurrentLogSegment,内部操作包括:首先log一下OP_END_LOG_SEGMENT事件,然后finalizeLogSegment这个区间的Transactions(其实就是把inprogress文件命名为以txid起始的文件名)。最后设置当前EditLog的state
2、然后开启新的logSegment,startLogSegment(nextTxId, true),在这里,首先已经移除的storageDirectory集合中遍历测试其是否已经恢复工作,然后依照规则产生新的InProgress文件并在文件上创建EditLogOutputStream流,最后在EditLog中log一下OP_START_LOG_SEGMENT这个事件
4、Editlog内涉及到Txid以及LogEdit,LogSync这一块有必要单独搞一遍文章来分析一下,这里简略先提一下:在log的时候,各个线程会更新一个全局的Txid,然后这个线程将自己ThreadLocal版本的myTxid也更新为这个Txid,这个过程是在beginTransaction内完成,然后在各个线程进行logSync的时候,首先同步的进行查询是否已经有sync进行和是否自己的myTxid是否大于syncIngID,如果是则等待别的线程的sync过程完成,否则判断是否自己的myTxid是否小于synctxid,如果是表名已经sync过了。否则设置isSyncRunning及sync为true开始进行sync,这个过程包括buf切换,flush到文件。最后设置好isSyncRuning为false等等收尾工作。
4、在进行完了triggerActiveLogRoll()之后,开始进行doTailEdits(),内部也分为四个步骤进行:
1、获取fsnamesystem的writelock
2、选取输入流,在有多个可选的EditLog流时,调用editLog .selectInputStreams(lastTxnId + 1, 0, null, false)来选择包含从lastTxnId日志的文件流,具体过程如下:
1、从所有的文件流中选取lastTxid大于这里指定txid的finallized过的EditLogs以及inprogress的EditLog,然后去掉startId相同的EditLog
2、检查这些文件的txid是否有空洞,checkForGaps看各个段的起始和结尾Txid是否相连。
3、skip到指定的txid
3、通过FSImage来loadEdits,EditLogLoader逐个去读取edit然后应用到当前的Namespace中(memory中)。
4、设置好lastLoadedTxnId = image.getLastAppliedTxId();
3、这里分析Checkpointer的行为,定期进行Checkpoint的实际工作是由CheckpointerThread来完成的。
1、首先从Namespace中获取最新的txid,看看和上次已经applyId的差距
2、查看上次Checkpoint的时候距离现在的时间差距是否过了一个周期
3、然后再查看是否设置阻止当前的Checkpoint,即preventCheckpointsUntil>now是否成立
4、如果ok的话,开始进行Checkpoint,这里主要完成两个步骤,一个是进行saveNamespace,一个是uploadFsimage:
1、SaveNamespace过程具体如下:
1、首先还是尝试恢复以前已经删除过的storageDirectory
2、查看当前Editlog的状态是否处于IN_SEGMENT状态,如果是,则进行endCurrentLogSegment。
3、针对每个StorageDirectory启动一个FSImageSaver进行save,save的过程中首先新建一个fsimage.ckpt(当然也带txid在后)为名字的文件。然后依据conf中的配置去创建一个压缩编码器然后通过这个压缩编码器进行save。save的过程中从FsDir的root开始一次一个目录级写入到FSImage,递归这个过程。
4、将所有的信息写入到各个storageDirectory的version文件中
5、写入最后一个Checkpoint的信息,storage .setMostRecentCheckpointInfo(txid, Util.now());
6、到各个StorageDirectory中去重命名fsimage.ckpt文件到正常fsimae文件
2、uploadFsimage过程具体如下:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值