HDFS的recoverLease和recoverBlock的過程分析

來源:互聯網
上載者:User

最近需要搞一下Lease,分析一下recoverLease的過程,順帶把recoverBlock的過程分析一下。

一、 recoverLease

recoverLease是恢複租約,我理解為釋放檔案之前的租約,close檔案,報告namenode。

recoverLease有兩條路徑去調用

1. DistributedFileSystem.create -> DFSClient.create -> Namenode.create -> FSNamesystem.startFile -> FSNamesystem.startFileInternal -> recoverLeaseInternal(myFile, src, holder, clientMachine, false)

這條路徑是在用戶端檔案create時調用的,此時它不需要close檔案。

2. DistributedFileSystem.recoverLease -> DFSClient.recoverLease -> Namenode.recoverLease(src,clientname) -> FSNamesystem.recoverLease(src,holder,clientMachine) -> recoverLeaseInternal(inode, src, holder, clientMachine, true)

這條路徑是在用戶端顯式調用一個path的recoverLease,此時它需要close檔案。[HDFS-1554]

以上兩個路徑,最終會調用FSNamesystem.recoverLeaseInternal,下面我們著重看一下recoverLeaseInternal,它主要做以下事情:

1. 獲得pendingfile,獲得當前holder的lease
2. 如果lease不為空白,且不是force,則AlreadyBeingCreatedException
3. 獲得當前client的lease,如果lease為空白,則AlreadyBeingCreatedException
4. 如果force則強制internalReleaseLeaseOne;否則,如果超過softlimit,也強制internalReleaseLease,但也拋出AlreadyBeingCreatedException。

它會通過調用internalReleaseLeaseOne實現對recoverBlock的執行。

recoverLeaseInternal -> internalReleaseLease -> internalReleaseLeaseOne

internalReleaseLeaseOne的過程:

1.找這個file的最後一個block的targets
2.pendingFile.assignPrimaryDatanode()  -> DatanodeDescriptor.addBlockToBeRecovered() -> recoverBlocks.offer

recoverBlocks會在datanode向namenode發送心跳包時,將recoverBlock的命令以NN_RECOVERY的holder身份返回給datanode,datanode執行命令。
3.reassignLease

二、recoverBlock過程

recoverBlock是在Datanode上執行的,有兩條路徑調用,一個由Namenode發起的,一個DFSClient發起的。

1. Namenode發起recoverBlock

  a)Namenode上的過程:

  Namenode.sendHeartbeat(datanode調用,向namenode發送心跳包,namenode返回i要執行的cmd -> FSNamesystem.handleHeartbeat ->

  DatanodeDescritor.getLeaseRecoveryCommand -> recoverBlocks.poll()

  按照上面recoverLease的分析,如果有recoverLease的請求,BlockQueue類型的recoverBlocks就有待處理的recoverBlock

 b)datanode上的過程

Datanode.run -> offerService()(一直運行,和namenode互動) ->  processCommand(cmds []) -> processCommand(cmd) ->
DNA_RECOVERBLOCK -> recoverBlocks(bcmd.getBlocks(), bcmd.getTargets()) -> recoverBlock(blocks[i], false, targets[i], true) 
[closeFile = true]

即datanode上有個心跳線程,預設每個3秒鐘,向namenode彙報心跳包,並獲得要在datanode上執行的cmd。如果有namenode發來的recoverBlock請求,

datanode上最終會調用recoverBlock方法,此時closeFile=true。它是recoverLease發起的,此時要關閉檔案,並使得這個檔案的block在datanode上的資訊一致。

2. DFSClient發起的recoverBlock

DFSClient.processDatanodeError ->DataNode.recoverBlock(Block block, boolean keepLength, DatanodeInfo[] targets) -> DataNode.recoverBlock(Block block, boolean keepLength, DatanodeInfo[] targets, false) [closeFile = false]

DFSClient通過dataStreamer發送block的packet資料,如果這個過程出現異常,會由processDatanodeError進行recover處理,即獲得pipeline中錯誤的datanode,在剩餘的兩個datanode選取一個datanode發起recoverBlock,從這個datanode開始重建pipeline。

此時調用datanode的recoverBlock傳遞的closeFile=false,因為在DFSClient寫入Block出現異常時,需要的是recover,不是關閉檔案。

關於recoverBlock(Block block, boolean keepLength, DatanodeInfo[] targets, boolean closeFile)

1.檢查ongoingRecovery中是否有這個block正在recover,如果有,則拋出IOException,Block is already being recovered, ignoring this request to recover it。如果沒有,則add進入ongoingRecovery
2.根據targets建立syncList,即明確向哪些節點sync哪個block

---> syncBlock
1.首先為這次syncBlock從namenode處獲得generationStamp
2.以新的generationStamp建立新的newBlock
3.對syncList中的每個datanode,執行updateBlock操作,將舊的block更新為newBlock
4.如果執行成功,向namenode報告commitBlockSynchronization,包含新的block和generationStamp
5.返回locatedBlock

---> updateBlock
1.FSDataset.updateBlock
2.如果finalize為true,FSDataset.finalizeBlockIfNeeded;通知namenode已經received block

以上,記錄以備忘。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.