1. 程式人生 > >NameNode元資料持久化

NameNode元資料持久化

NameNode在記憶體中儲存著整個檔案系統的名字空間和檔案資料塊對映(Blockmap)的映像。
如果NameNode宕機,那麼整個叢集就癱瘓了

因而則出現了元資料的儲存問題,接下來請看如下幾個問題

如果元資料僅以檔案的形式儲存在namenode本地硬碟行不行呢?
    因為大批量的客戶端同時在進行上傳、下載等各種操作時,都要對元資料進行讀寫及修改操作
    僅僅以檔案的形式來儲存元資料顯然不行,因為無法做到對各種操作的快速響應
    把元資料放在記憶體中呢,確實能夠提高系統響應速度,但是一旦斷電就完全丟失了,這肯定也不行

那麼如果把記憶體的資料定期flush到磁碟檔案的方法行不行呢?
    一旦斷電,沒來得及的刷到磁碟的記憶體資料肯定也是要丟失的,顯然也不行

那麼在實際環境中,hadoop是怎麼管理元資料的呢?
    首先,磁碟確實有塊空間,對元資料進行持久化儲存的,名為fsimage
    如果直接讀取磁碟檔案,速度肯定跟不上,記憶體中也要放一些元資料資訊
    雖然很容易丟失,但可以提供查詢服務,實際上就是讀寫分離,由讀寫分離就有了資料一致性的問題

因為寫入資料,沒有寫入記憶體中,最新的元資料記錄在哪呢?
    實際上是記錄在edits.log中,這個檔案不提供修改,只提供追加,以日誌的形式記錄
    比如在上傳一個檔案時,先對namenode進行詢問,往哪裡寫,namenode一邊分配一邊記錄
    將空間分配資訊記錄edits.log,當完成一個副本的寫入工作後,通知namenode,被認為是寫入成功
    這時,將edits.log的資料更新至記憶體,此時,記憶體中的資料是最新的
    即使現在斷電,最新的元資料在edits.log也有儲存。

當客戶端執行寫操作時,NameNode會先在編輯日誌中寫下記錄,並在記憶體中保持一個檔案系統元資料
元資料會在編輯日誌有所改動後進行更新。記憶體中的元資料用來提供讀資料請求服務

過程分析:

1.客戶端寫入檔案時,NameNode首先在edits.log檔案中記錄元資料操作
2.操作完成後將成功資訊傳送給NameNode。NameNode在記憶體中寫入這次操作新產生的元資料資訊
更新的順序edits.log-----記憶體-----fsimage

fsimage合併操作:

為防止影響響應速度,由SecondaryNamenode來合併
當edits*.log寫滿或時間達到1h時,通知SecondaryNamenode進行checkpoint操作

【checkpoint】操作

1.輔助Namenode請求主Namenode停止使用edits檔案,暫時將新的寫操作記錄到一個新檔案中,如edits.new。
2.輔助Namenode節點從主Namenode節點獲取fsimage和edits檔案(採用HTTP GET)
3.輔助Namenode將fsimage檔案載入到記憶體,逐一執行edits檔案中的操作,建立新的fsimage檔案
4.輔助Namenode將新的fsimage檔案傳送回主Namenode(使用HTTP POST)
5.主Namenode節點將從輔助Namenode節點接收的fsimage檔案替換舊的fsimage檔案
  用步驟1產生的edits.new檔案替換舊的edits檔案(即改名)。同時更新fstime檔案來記錄檢查點執行的時間

校驗點的目的:

通過把hdfs檔案系統元資料的快照儲存到FsImage中從而保持了hdfs檔案系統的一致性。

校驗點觸發方式:

1.根據時間迴圈(dfs.namenode.checkpoint.period)單位是秒觸發
2.根據檔案系統的事務增加量(dfs.namenode.checkpoint.txns)觸發
  如果兩個都進行了設定,那麼哪個先達到了,就會觸發校驗點。

【備註】
儘管讀取FsImage是有效的,但是在FsImage檔案後附加是無效的。
相對於修改FsImage,更建議修改EditLog檔案。在執行校驗點的過程中就是把EditLog轉換到FsImage中的過程。