HDFS 05 - HDFS 的元數據管理(FSImage、Edits、CheckPoint)


1 - NameNode 的元數據

NameNode 的所有操作及整個集群的狀態都存儲在 元數據 中,元數據通過 FSImage 和 Edits 文件保存。

【輔助理解】NameNode 的元數據存儲在哪里?
假設:如果元數據存儲在 NameNode 節點的磁盤中,由於需要頻繁地隨機訪問,還要響應客戶請求,效率會很低。因此元數據需要放在內存中。
但如果只存到內存中,一旦機器斷電,元數據就會丟失,整個集群就無法工作了。
—— 因此需要在磁盤中備份元數據的 FSImage。

【 新問題】內存中的元數據更新時,如果同時更新 FSImage,效率會很低,但如果不更新 FSImage,就容易出現一致性問題,一旦 NameNode 斷電,就會丟失數據。
—— 因此引入 Edits 文件(只追加,效率很高),每當元數據需要添加或更新時,既修改內存中的元數據,並追加到 Edits 文件中。
—— 即使 NameNode 節點斷電,也可以通過 FSImage 和 Edits 的合並,合成元數據。

它們的主要作用是:在集群啟動時將集群的狀態恢復到關閉前的狀態

—— 也就是 Hadoop 集群因為各種原因需要重新啟動,元數據能保證集群啟動之后的狀態和上次停止前的狀態一致。

第一次啟動 NameNode 前的格式化(hdfs namenode -format)操作會創建 fsimage 和 edits 文件。

非第一次啟動,NameNode 會進行數據恢復:首先把 fsimage 加載到內存中形成文件系統鏡像,然后再把 edits 中 fsimage_txid 之后的、所有事務 回放到這個文件系統鏡像上。這個時候,集群也就恢復到關閉前的狀態了。

它們的位置需要在 hdfs-site.xml 文件中指定:

<!-- NameNode 元數據的存放目錄 -->
<property>
    <name>dfs.namenode.name.dir</name>    
    <value>file:/Users/healchow/data/hadoop/namenode</value>
</property>
<!-- NameNode 日志文件的存放目錄 -->
<property>
     <name>dfs.namenode.edits.dir</name>
     <value>file:/Users/healchow/data/hadoop/namenode/edits</value
</property>

1.1 FSImage 元數據鏡像

1)FSImage 是 NameNode 中關於元數據的鏡像,一般稱為檢查點的鏡像;會在內存和磁盤中各保存一份;

2)FSImage 是 NameNode 自最后一次 CheckPoint 之前的全部元數據,並不是實時的數據

3)FSImage 保存了 NameNode 管理下的所有 DataNode 的文件和目錄信息:

對文件來說:包括文件的 block、各個 block 所在的 DataNode,以及它們的修改時間、訪問時間等;

對目錄來說:包括修改時間、訪問權限控制信息(權限、屬組)等。

FSImage 默認會保存2個,由屬性 dfs.namenode.num.checkpoints.retained 控制。

內存中的 FSImage 用於 NameNode 向客戶端提供讀服務,而 EditLog 僅僅只是在數據恢復的時候發揮作用。

1.2 查看 FSImage 文件

FSImage 文件的文件名形如 fsimage_${end_txid},其中 ${end_txid} 表示這個 FSImage 文件中的最后一個事務的 id。

查看 FSImage 文件中的信息:

# hdfs oiv 回車后會顯示命令的幫助信息:

cd ~/bigdata/data/hadoop/namenode
hdfs oiv -i fsimage_0000000000000000864 -p XML -o hello.xml

1.3 Edits 操作日志

1)客戶端對 HDFS 的寫操作會先記錄到 edits 文件中 —— 自最后一次檢查點之后的所有操作,有實時數據;

HDFS 客戶端提交的創建、移動、刪除文件等 寫操作 的時候,NameNode 會首先把這些操作記錄在 edits 文件中。

2)edits 修改完成之后,會再更新內存中的文件系統鏡像;

edits 文件會不斷增大(導致系統運行、重啟恢復等過程非常緩慢),在一定條件下會和 fsimage 文件合並,從而減小 edits 文件的體積。

3)記錄在 edits 中的每一個操作又稱為一個事務,每個事務有一個整數形式的事務 id 作為編號。

(臨時總結,不一定對)EditLog 就是事務日志,主要作用是用來記錄寫操作,以支持系統的恢復。

1.4 查看 Edits 文件

Edits 會被切割成很多段,每一段稱為一個 Segment。正在寫入的 Segment 處於 in-progress 狀態,其文件名形如 edits_inprogress_${start_txid},其中 ​${start_txid} 表示這個 Segment 的起始事務 id。

已經寫入完成的 Segment 處於 finalized 狀態,其文件名形如 edits_${start_txid}-${end_txid},其中 ${start_txid} 表示這個 Segment 的起始事務 id,${end_txid} 表示這個 Segment 的結束事務 id。

查看 Edits 中的文件信息

# hdfs oev 回車后會顯示命令的幫助信息:
cd ~/data/hadoop/namenode
hdfs oev -i edits_0000000000000000865-0000000000000000866 -p XML -o myedit.xml

2 - NameNode 的啟動流程

1)Loading FSImage - 從 FSImage File 中讀取最新的元數據快照(最近生成的 fsimage_txid);

2)Loading Edits - 讀取 fsimage_txid 之后的所有事務的 Eidts,將 Eidts 中的操作重新執行一遍,此時 NameNode 就恢復到上次停止時的狀態了;

3)CheckPoint - 將當前狀態寫入新的 CheckPoint (檢查點)中,即產生一個新的 fsimage.ckpt_txid 文件;

4)Safe mode - 等待各個 DataNodes 匯報自己的 block 信息,形成 blockMap,然后退出安全模式。

此時 NameNode 啟動結束,等待接受用戶的操作請求,並把用戶操作寫入新的 Eidts 中,定期進行 CheckPoint,對元數據執行快照。

3 - CheckPoint 檢查點操作

3.1 為什么要 CheckPoint

HDFS 的每個寫操作都會寫入 edits 中,如果集群規模非常龐大,操作又很頻繁,隨着時間的積累 edits 會變的很大,極端情況下會占滿整個磁盤。

另外,由於 NameNode 在啟動的時候,需要將 edits 中的操作重新執行一遍,過大的 edits 會延長 NameNode 的啟動時間。

所以,通過 CheckPoint 定期對元數據進行合並。

3.2 CheckPoint 的過程

CheckPoint 會把 FSImage 和 EditLog 的內容進行合並生成一個新的 FSImage。

這樣在 NameNode 啟動的時候就不用將巨大的 EditLog 中的事務再執行一遍,而是直接加載合並之后的新 FSImage ,然后重新執行未被合並的 EditLog 文件就可以了。

創建新 FSImage 的過程需要大量的I/O、內存等資源,為了減輕影響,可將 Checkpoint 過程放在 SecondaryNameNode 或 StandbyNameNode 中(不同機器上)。

NameNode 在 Checkpoint 的時候會限制用戶的訪問(Hadoop 進入安全模式,此時需要管理員使用 dfsadmin 的 save namespace 來創建新的檢查點);

4 - SecondaryNameNode 輔助管理 FSImage 和 EditLog

【輔助理解】如果 Edits 文件被長時間追加,會導致該文件非常龐大,而且異常斷電情況下,恢復元數據所需的時間也會很長。

—— 因此需要定期合並 FSImage 和 Edits,如果由 NameNode 節點去執行合並操作,會降低 NameNode 處理客戶端請求的效率。
—— 因此引入一個新的節點 SecondaryNamenode,專門用於 FSImage 和 Edits 文件的合並。

4.1 管理元數據的相關配置

SNN(SecondaryNameNode,備份 NameNode)節點要在 conf/masters 文件中指定;

SNN 的 hdfs-site.xml 文件中需要配置下述參數:

<property>
  <name>dfs.http.address</name>
  <value>host:50070</value>
</property>

SecondaryNameNode 會定期合並 FSImage 和 EditLog,把 EditLog的體積控制在一個合理的范圍內。

Checkpoint 的觸發條件取決於兩個參數,可在 NameNode / SNN 的 core-site.xml 中配置:

<!-- 兩次 checkpoint 的時間間隔,默認3600秒,即1小時 -->
<property>
    <name>dfs.namenode.checkpoint.period</name>
    <value>3600s</value>
</property>
<!-- 新生成的 EditLog 中積累的事務數量達到了閾值,默認1000000次。優先級高於上述參數 -->
<property>
    <name>dfs.namenode.checkpoint.txns</name>
    <value>1000000</value>
</property>
<!-- 每隔多久檢查一次 HDFS 未記錄到檢查點的事務數,默認60秒 -->
<property>
    <name>dfs.namenode.checkpoint.check.period</name>
    <value>60s</value>
</property>

<!-- 一次記錄文件的大小,默認64MB -->
<property>
    <name>fs.checkpoint.size</name>
    <value>67108864</value>
</property>

4.2 管理元數據的流程

上面配置的2個條件,如果有任意一個滿足了,就會觸發 SecondaryNameNode 合並 FSImage 和 EditLog,具體流程為:

1)SecondaryNameNode 通知 NameNode 停止使用 EditLog,暫時將新的寫操作存放到 edits.new 文件;

2)SecondaryNameNode 通過 HTTP GET 請求,從 NameNode 中獲取 FSImage 和 EditLog,將它們加載到自己的內存中;

3)SecondaryNameNode 合並 FSImage 和 EditLog,合並完成后生成新的 FSImage,命名為 fsimage.ckpt

4)SecondaryNameNode 通過 HTTP POST 請求方式,將新的 fsimage.ckpt 發送給 NameNode;

5)NameNode 把 fsimage.ckpt 改為 fsimage(覆蓋掉原來的),並刪掉舊的 edits 文件,把 edits.new 重命名為 edits,最后更新 fstime(即最后一個檢查點的時間戳)。

通過這一系列操作,就避免了 edits 日志的無限增長,加快 Namenode 的啟動過程。

參考資料

NameNode原數據及checkpoint分析


版權聲明

作者:瘦風(https://healchow.com)

出處:博客園-瘦風的南牆(https://www.cnblogs.com/shoufeng)

感謝閱讀,公眾號 「瘦風的南牆」 ,手機端閱讀更佳,還有其他福利和心得輸出,歡迎掃碼關注🤝

本文版權歸博主所有,歡迎轉載,但 [必須在頁面明顯位置標明原文鏈接],否則博主保留追究相關人士法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM