DatanodeDescriptor說明

DatanodeDescriptor類記錄了Datanode的使用情況,如capacity,used等統計信息,DatanodeDescriptor是Namenode內部的數據結構,並不是通過RPC通信從Datanode向Namenode通信時候使用。Namenode從DatanodeDescriptor中讀取Datanode統計信息,並顯示在jsp頁面上,這就是在網頁上面顯示的統計信息的來源。
public class DatanodeDescriptor extends DatanodeInfo 首先來看一下DatanodeInfo
1. public class DatanodeInfo extends DatanodeID implements Node
1) 看一下DatanodeID類
public String name;
public String storageID;
protected int infoPort;
public int ipcPort;
有如上四個變量,name表示了名稱,storageID是ID號唯一,infoPort是infoServer運行的端口,ipcPort是ipc運行的端口,剩下的就是getter和setter方法。
2) DatanodeInfo中的變量有
protected long capacity;
protected long dfsUsed;
protected long remaining;
protected long lastUpdate;
protected int xceiverCount;
protected String hostName = null;
這些變量是Datanode統計信息,要通過RPC通信在Namenode啓動時將這些狀態傳遞從Datanode傳遞給Namenode,剩下的方法也比較簡單,基本上是getter和setter
public String getDatanodeReport() 方法,按照一定的格式輸出Datanode統計信息。
同時,DatanodeInfo類中還有一個Node parent變量,這個變量是爲了計算拓撲結構使用。
2. 解決了DatanodeInfo繼續看DatanodeDescriptor,下面一個結構爲BlockTargetPair
BlockTargetPair維護了一個Block和DatanodeDescriptor數組變量。爲下面的變量提供了數據結構。
3. private static class BlockQueue 變量有
1) private final Queue<BlockTargetPair> blockq = new LinkedList<BlockTargetPair>();
2) synchronized boolean offer(Block block, DatanodeDescriptor[] targets) 入鏈表
3) synchronized List<BlockTargetPair> poll(int numBlocks) 出鏈表
4. private volatile BlockInfo blockList = null;
DatanodeDescriptor中維護了一個BlockInfo對象,是該Datanode對應的block的頭結點,通過頭結點可以遍歷該Datanode上面的所有block。可以配合blocksMap理解這個結構。
5. 下面是三個重要變量
/** A queue of blocks to be replicated by this datanode */
private BlockQueue replicateBlocks = new BlockQueue();
        /** A queue of blocks to be recovered by this datanode */
private BlockQueue recoverBlocks = new BlockQueue();
        /** A set of blocks to be invalidated by this datanode */
private Set<Block> invalidateBlocks = new TreeSet<Block>();
這三個變量分別代表了需要複製的 block鏈表,需要recovery的block鏈表,以及無效的block表。
6. boolean addBlock(BlockInfo b)
向該Datanode添加block,具體方法是:
blockList = b.listInsert(blockList, this);
其中參數中的blockList是頭結點,返回值是新的頭結點,指向的是新添加的block對應的BlockInfo變量。
7. boolean removeBlock(BlockInfo b)
向該Datanode刪除block,具體方法是:
blockList = b.listRemove(blockList, this);
從blockMap鏈表結構中刪除該block,返回頭結點,blockList仍然維護的是一個頭結點。
8. void moveBlockToHead(BlockInfo b)
將某個BlockInfo對應的對象放在blocksMap結構的頭結點,方法是先刪除,在插入。
blockList = b.listRemove(blockList, this);
blockList = b.listInsert(blockList, this);
9. public int numBlocks()
根據頭結點遍歷所有block,獲得該datanode上面所有block數量。
10. static private class BlockIterator implements Iterator<Block>
迭代器模式。
11. void addBlockToBeReplicated(Block block, DatanodeDescriptor[] targets)
void addBlockToBeRecovered(Block block, DatanodeDescriptor[] targets)
void addBlocksToBeInvalidated(List<Block> blocklist)
往相應的結構裏面放,見5。
12. BlockCommand getReplicationCommand(int maxTransfers)
BlockCommand getLeaseRecoveryCommand(int maxTransfers)
BlockCommand getInvalidateBlocks(int maxblocks)
這些函數是要通過RPC傳遞給Datanode,datanode根據傳遞的信息進行相應操作,放到後面再說。
13. void reportDiff(BlocksMap blocksMap,
                 BlockListAsLongs newReport,
                 Collection<Block> toAdd,
                 Collection<Block> toRemove,
                 Collection<Block> toInvalidate)
這是DatanodeDescriptor中最重要的一個方法,從Datanode心跳彙報得到的塊信
信息經過分類後傳遞給DatanodeDescriptor,進行統計分類。在想Namenode反饋
需要添加,需要移除以及無效的塊集合。newReport是從datanode中通過RPC獲
得的塊信息。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章