1. 程式人生 > 實用技巧 >畫圖詳解HDFS元資料合併流程

畫圖詳解HDFS元資料合併流程

合併元資料的原因

首先要知道磁碟和記憶體中都儲存有元資料,磁碟中的原資料是由正在編輯的日誌檔案(edits_inprogress)和映象檔案(fsimage)組成。

當客戶端傳送增刪改的請求,由於磁碟的讀寫比較慢,不能及時地修改映象檔案中的目錄樹結構,所以會先將請求寫入到edits_inprogress檔案中(追加寫入),記錄下請求。然後將請求傳送到記憶體中,這時會及時地修改元資料中的目錄結構,所以記憶體中的元資料永遠是最新、最完整的。

時間一長,記憶體中的元資料資訊就和磁碟中的元資料資訊相差越來越大,所以需要將磁碟中的映象檔案和正在編輯的日誌檔案定期合併。

元資料合併流程

  1. 客戶端傳送增刪改請求,比如:hadoop fs -mkdir /test

    。會先將請求寫入磁碟的正在編輯的日誌檔案中(edits_inprogress)。

  2. 然後將請求寫入記憶體,這時,記憶體中的元資料會及時地被修改。即會在根目錄下建立一個test目錄,這時我們重新整理hdfs的檔案系統介面就會看到生成了一個test目錄。

  3. SecondaryNameNode定期地向NameNode傳送合併元資料的請求,這時,NameNode會檢查合併元資料的條件是否滿足,如果滿足就開始合併元資料。觸發元資料合併的條件如下:

    <!--時間間隔:3600s=1h-->
    <property>
      <name>dfs.namenode.checkpoint.period</name>
      <value>3600</value>
      <description>The number of seconds between two periodic checkpoints.
      </description>
    </property>
    
    <!--元資料條數:1000000條-->
    <property>
      <name>dfs.namenode.checkpoint.txns</name>
      <value>1000000</value>
      <description>The Secondary NameNode or CheckpointNode will create a checkpoint
      of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
      of whether 'dfs.namenode.checkpoint.period' has expired.
      </description>
    </property>
    

    以上兩個條件只要滿足一個就開始合併元資料。

  4. 如果合併元資料的條件滿足,NameNode會將正在編輯的日誌檔案回滾,形成歷史日誌檔案。比如上圖中,將edits_inprogress_07回滾為edits_07檔案。

  5. SecondaryNameNode會從NameNode節點將歷史日誌檔案和映象檔案拉取到自己的節點。
    這裡要注意的一點是,如果不是第一次進行元資料合併,那麼這次拉取的日誌檔案是編號從合併點記錄的日誌檔案編號開始到最新回滾的日誌檔案編號之間的所有日誌檔案,不需要全部將日誌檔案拉取過來,並且也不需要再拉取映象檔案。

    舉個栗子,假如合併點檔案(seen_txid)記錄的編號是7,那麼就只需要把回滾出來的edits_07檔案拉取到SecondaryNameNode節點。

    如果是第一次合併元資料,那麼就需要將所有的日誌檔案資料和映象檔案一起拉取到SecondaryNameNode。

  6. SecondaryNameNode將日誌檔案和映象檔案拉取到記憶體中進行元資料合併。合併的過程其實就是根據日誌檔案中記錄下來的增刪改操作改變映象檔案中的元資料資訊(目錄結構)。

  7. 合併完成之後,SecondaryNameNode將合併完成的映象檔案(fsimage.checkpoint)傳送給NameNode,並且自己也會保留一份到磁碟。

  8. NameNode會將fsimage.checkpoint檔案重新命名為fsimage檔案,並且替換掉原來的fsimage檔案。

元資料合併的注意事項

在沒有達到checkpoint條件的這段時間,如果叢集正常關閉,那麼這個時候記憶體中的元資料在叢集關閉前會dump到磁碟。舉個栗子,當我們在hdfs根目錄下建立了test目錄之後正常關閉叢集,再次啟動之後,會發現我們建立的test目錄仍然存在,就是因為記憶體中的元資料dump到了磁碟。