源代碼分析(三四)
繼續(xù)對NameNode實現(xiàn)的接口做分析。
publicDatanodeCommand blockReport(DatanodeRegistration nodeReg,
long[]blocks) throws IOException
DataNode向NameNode報告它擁有的所有數(shù)據(jù)塊,其中,參數(shù)blocks包含了數(shù)組化以后數(shù)據(jù)塊的信息。FSNamesystem.processReport處理這個請求。一番檢查以后,調(diào)用DatanodeDescriptor的reportDiff,將上報的數(shù)據(jù)塊分成三組,分別是:
l 刪除:其它情況;
l 加入:BlocksMap中有數(shù)據(jù)塊,但目前的DatanodeDescriptor上沒有對應信息;
l 使無效:BlocksMap中沒有找到數(shù)據(jù)塊。
對于刪除的數(shù)據(jù)塊,調(diào)用removeStoredBlock,這個方法我們前面已經(jīng)分析過啦。
對應需要加入的數(shù)據(jù)塊,調(diào)用addStoredBlock方法,處理流程如下:
l 從BlocksMap獲取現(xiàn)在的信息,記為storedBlock;如果為空,返回;
l 記錄block和DatanodeDescriptor的關(guān)系;
l 新舊數(shù)據(jù)塊記錄不是同一個(我們這個流程是肯定不是啦):
1. 如果現(xiàn)有數(shù)據(jù)塊長度為0,更新為上報的block的值;
2. 如果現(xiàn)有數(shù)據(jù)塊長度比新上報的長,invalidateBlock(前面分析過,很簡單的一個方法)當前數(shù)據(jù)塊;
3. 如果現(xiàn)有數(shù)據(jù)塊長度比新上報的小,那么會刪除所有老的數(shù)據(jù)塊(還是通過invalidateBlock),并更新BlocksMap中數(shù)據(jù)塊的大小信息;
4. 跟新可用存儲空間等信息;
l 根據(jù)情況確定數(shù)據(jù)塊需要復制的數(shù)目和目前副本數(shù);
l 如果文件處于構(gòu)建狀態(tài)或系統(tǒng)現(xiàn)在是安全模式,返回;
l 處理當前副本數(shù)和文件的目標副本數(shù)不一致的情況;
l 如果當前副本數(shù)大于系統(tǒng)設(shè)定門限,開始刪除標記為無效的數(shù)據(jù)塊。
還是給個流程圖吧:
對于標記為使無效的數(shù)據(jù)塊,調(diào)用addToInvalidates方法,很簡單的方法,直接加到FSNamesystem的成員變量recentInvalidateSets中。
publicvoid blockReceived(DatanodeRegistrationregistration,
Blockblocks[],
String[] delHints)
DataNode可以通過blockReceived,向NameNode報告它最近接受到的數(shù)據(jù)塊,同時給出如果數(shù)據(jù)塊副本數(shù)太多時,可以刪除數(shù)據(jù)塊的節(jié)點(參數(shù)delHints)。在DataNode中,這個信息是通過方法notifyNamenodeReceivedBlock,記錄到對應的列表中。
NameNode上的處理不算復雜,對輸入?yún)?shù)進行檢查以后,調(diào)用上面分析的addStoredBlock方法。然后在PendingReplicationBlocks對象中刪除相應的block。
publicvoid errorReport(DatanodeRegistration registration,
interrorCode,
String msg)
向NameNode報告DataNode上的一個錯誤,如果錯誤是硬盤錯,會刪除該DataNode,其它情況只是簡單地記錄收到一條出錯信息。
publicNamespaceInfo versionRequest() throws IOException;
從NameNode上獲取NamespaceInfo,該信息用于構(gòu)造DataNode上的DataStorage。
UpgradeCommand processUpgradeCommand(UpgradeCommand comm) throwsIOException;
我們不討論。
public voidreportBadBlocks(LocatedBlock[] blocks) throws IOException
報告錯誤的數(shù)據(jù)塊。NameNode會循環(huán)調(diào)用FSNamesystem的markBlockAsCorrupt方法。處理流程不是很復雜,找對應的INodeFile,如果副本數(shù)夠,那么調(diào)用invalidateBlock,使該DataNode上的Block無效;如果副本數(shù)不夠,加Block到CorruptReplicasMap中,然后準備對好數(shù)據(jù)塊進行復制。
目前為止,我們已經(jīng)完成了NameNode上的ClientProtocol和DatanodeProtocol的分析了,NamenodeProtocol我們在理解從NameNode的時候,才會進行分析。
免責聲明:以上內(nèi)容源自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請告知,我們將盡快刪除相關(guān)內(nèi)容。