NameNode任務線程之PendingReplicationBlocks$PendingReplicationMonitor

在前面我已經詳細的講到了一些NameNode的後臺工作線程,但是關於PendingReplicationBlocks$PendingReplicationMonitor和FSNamesystem$ReplicationMonitor,它們倆實在是讓我很糾結,因爲我真的不知道應該先講哪一個。經過好幾天的思量之後。還是決定先講一講PendingReplicationMonitor吧!難過

         先來看看PendingReplicationMonitor在NameNode中是幹什麼的吧,但恰恰是這兒讓我頭疼的地方!還是先簡單的說說ReplicationMonitor,NameNode節點用它來定期的檢測數據塊Block是否滿足設定的副本數量,對於沒有達到副本數量的Blocks,NameNode會命令響應的DataNode節點去copy它,使它滿足副本數量,DataNode複製Block是需要時間的,同時DataNode在複製Block的時候可能會出現意外的情況而失敗,那麼NameNode是如何發現DataNode節點複製Block的副本失敗的呢?這就需要一種檢查機制,也就是PendingReplicationMonitor要乾的事情了。好了,讓源代碼來說話吧。先看看PendingReplicationBlocks類:

pendingReplications:存放正在被數據節點copy副本的Blocks,key是block,value是副本數量

timeOutItems:存放數據節點copy副本超時的Blocks(copy失敗,需要重新安排數據節點copy副本)

timerThread:PendingReplicationMonitor監控線程

timeout:數據節點copy副本的超時時間(由配置文件的dfs.replication.pending.timeout.sec項設置(單位秒))

defaultRecheckInterval:一次檢測所有正在copy的Block是否超時的間隔時間

      當NameNode節點安排數據節點copy Block的副本時,會把該Block放入pendingReplications中,當然還有copy數量;當數據節點完成Block的接受或者是copy時,會調用遠程方法blocksReceive,在blocksReceive方法裏面,會刪除pendingReplications中與block相關的一些信息。下面來具體看看PendingReplicationMonitor

class PendingReplicationMonitor implements Runnable {
      
    public void run() {
      while (fsRunning) {
        long period = Math.min(defaultRecheckInterval, timeout);
        try {
           //檢測正在copy的block副本是否copy失敗
          pendingReplicationCheck();
          
          Thread.sleep(period);
        } catch (InterruptedException ie) {
          FSNamesystem.LOG.debug( "PendingReplicationMonitor thread received exception. " + ie);
        }
      }
    }

    /**
     * Iterate through all items and detect timed-out items
     */
    void pendingReplicationCheck() {
      synchronized (pendingReplications) {
        Iterator iter = pendingReplications.entrySet().iterator();
        long now = FSNamesystem.now();
        while (iter.hasNext()) {
          Map.Entry entry = (Map.Entry) iter.next();
          PendingBlockInfo pendingBlock = (PendingBlockInfo) entry.getValue();
          if (now > pendingBlock.getTimeStamp() + timeout) {
            Block block = (Block) entry.getKey();
            synchronized (timedOutItems) {
              timedOutItems.add(block);
            }
            FSNamesystem.LOG.warn("PendingReplicationMonitor timed out block " + block);
            
            iter.remove();
          }
        }
      }
    }
  }

從上面的代碼可以看出,PendingReplicationMonitor線程會把copy失敗的Blocks放到timedOutItems中,那麼對於這些Blocks,NameNode節點是如何處理的呢?實際上他們會被ReplicationMonitor再次借交給其它的數據節點備份,就這麼簡單。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章