源代碼分析(三五)
除了對外提供的接口,NameNode上還有一系列的線程,不斷檢查系統(tǒng)的狀態(tài),下面是這些線程的功能分析。
在NameNode中,定義了如下線程:
Daemon hbthread= null; // HeartbeatMonitor thread
publicDaemon lmthread = null; // LeaseMonitor thread
Daemon smmthread= null; // SafeModeMonitor thread
publicDaemon replthread = null; // Replication thread
privateDaemon dnthread = null;
PendingReplicationBlocks中也有一個線程:
Daemon timerThread= null;
NameNode內(nèi)嵌的HTTP服務(wù)器中自然也有線程,這塊我們就不分析啦。
HttpServer infoServer;
心跳線程用于對DataNode的心態(tài)進行檢查,以間隔heartbeatRecheckInterval運行heartbeatCheck方法。如果在一定時間內(nèi)沒收到DataNode的心跳信息,我們就認(rèn)為該節(jié)點已經(jīng)死掉,調(diào)用removeDatanode(前面分析過)將DataNode標(biāo)記為無效。
租約lmthread用于檢查租約的硬超時,如果租約硬超時,調(diào)用前面分析過的internalReleaseLease,釋放租約。
smmthread運行的SafeModeMonitor我們前面已經(jīng)分析過了。
replthread運行ReplicationMonitor,這個線程會定期調(diào)用computeDatanodeWork和processPendingReplications。
computeDatanodeWork會執(zhí)行computeDatanodeWork或computeInvalidateWork。computeDatanodeWork從neededReplications中掃描,取出需要復(fù)制的項,然后:
l 檢查文件不存在或者處于構(gòu)造狀態(tài);如果是,從隊列中刪除復(fù)制項,退出對復(fù)制項的處理(接著處理下一個);
l 得到當(dāng)前數(shù)據(jù)塊副本數(shù)并選擇復(fù)制的源DataNode,如果空,退出對復(fù)制項的處理;
l 再次檢查副本數(shù)(很可能有DataNode從故障中恢復(fù)),如果發(fā)現(xiàn)不需要復(fù)制,從隊列中刪除復(fù)制項,退出對復(fù)制項的處理;
l 選擇復(fù)制的目標(biāo),如果目標(biāo)空,退出對復(fù)制項的處理;
l 將復(fù)制的信息(數(shù)據(jù)塊和目標(biāo)DataNode)加入到源目標(biāo)DataNode中;在目標(biāo)DataNode中記錄復(fù)制請求;
l 從隊列中將復(fù)制項移動到pendingReplications。
可見,這個方法執(zhí)行后,復(fù)制項從neededReplications挪到pendingReplications中。DataNode在某次心跳的應(yīng)答中,可以拿到相應(yīng)的信息,執(zhí)行復(fù)制操作。
computeInvalidateWork當(dāng)然是用于刪除無效的數(shù)據(jù)塊。它的主要工作在invalidateWorkForOneNode中完成。和上面computeDatanodeWork類似,不過它的處理更簡單,將recentInvalidateSets的數(shù)據(jù)通過DatanodeDescriptor.addBlocksToBeInvalidated挪到DataNode中。
dnthread執(zhí)行的是DecommissionedMonitor,它的run方法周期調(diào)用decommissionedDatanodeCheck,再到checkDecommissionStateInternal,定期將完成Decommission任務(wù)的DataNode狀態(tài)從DECOMMISSION_INPROGRESS改為DECOMMISSIONED。
PendingReplicationMonitor中的線程用于對處在等待復(fù)制狀態(tài)的數(shù)據(jù)塊進行檢查。如果發(fā)現(xiàn)長時間該數(shù)據(jù)塊沒被復(fù)制,那么會將它挪到timedOutItems中。請參考PendingReplicationBlocks的討論。
infoServer的相關(guān)線程我們就不分析了,它們都用于處理HTTP請求。
上面已經(jīng)總結(jié)了NameNode上的一些為特殊任務(wù)啟動的線程,除了這些線程,NameNode上還運行著RPC服務(wù)器的相關(guān)線程,具體可以看前面章節(jié)。
在我們開始分析Secondary NameNode前,我們給出了以NameNode上一些狀態(tài)轉(zhuǎn)移圖,大家可以通過這個圖,更好理解NameNode。
NameNode:
DataNode:
文件:
Block,比較復(fù)雜:
上面的圖不是很嚴(yán)格,只是用于幫助大家理解NameNode對Block復(fù)雜的處理過程。
稍微說明一下,“Block in initedDataNode”表明這個數(shù)據(jù)塊在一個剛初始化的DataNode上。“Block in INodeFile”是數(shù)據(jù)塊屬于某個文件,“Block in INodeFileUnderConstruction” 表明這數(shù)據(jù)塊屬于一個正在構(gòu)建的文件,當(dāng)然,處于這個狀態(tài)的Block可能因為租約恢復(fù)而轉(zhuǎn)移到“Block in Recover”。右上方描述了需要復(fù)制的數(shù)據(jù)塊的狀態(tài),UnderReplicatedBlocks和PendingReplicationBlocks的區(qū)別在于Block是否被插入到某一個DatanodeDescriptor中。Corrupt和Invalidate的就好理解啦。
免責(zé)聲明:以上內(nèi)容源自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請告知,我們將盡快刪除相關(guān)內(nèi)容。