HDFS元數據,按類型分,主要包括如下幾個部分:node
一、文件、目錄自身的屬性信息,例如文件名,目錄名,修改信息等。安全
二、文件記錄的信息的存儲相關的信息,例如存儲塊信息,分塊狀況,副本個數等。網絡
三、記錄 HDFS 的 Datanode 的信息,用於 DataNode 的管理。數據結構
按形式分爲內存元數據和元數據文件兩種,分別存在內存和磁盤上。oop
HDFS 磁盤上元數據文件分爲兩類,用於持久化存儲:spa
fsimage 鏡像文件:是元數據的一個持久化的檢查點,包含 Hadoop 文件系統中的全部目錄和文件元數據信息,但不包含文件塊位置的信息。文件塊位置信息只存儲在內存中,是在 datanode 加入集羣的時候,namenode 詢問 datanode 獲得的,而且間斷的更新。設計
Edits 編輯日誌:存放的是 Hadoop 文件系統的全部更改操做(文件建立,刪除或修改)的日誌,文件系統客戶端執行的更改操做首先會被記錄到 edits 文件中。日誌
fsimage 和 edits 文件都是通過序列化的,在 NameNode 啓動的時候,它會將 fsimage文件中的內容加載到內存中,以後再執行 edits 文件中的各項操做,使得內存中的元數據和實際的同步,存在內存中的元數據支持客戶端的讀操做,也是最完整的元數據。code
當客戶端對 HDFS 中的文件進行新增或者修改操做,操做記錄首先被記入 edits 日誌文件中,當客戶端操做成功後,相應的元數據會更新到內存元數據中。由於 fsimage 文件通常都很大(GB 級別的很常見),若是全部的更新操做都往 fsimage 文件中添加,這樣會致使系統運行的十分緩慢。orm
HDFS 這種設計實現着手於:一是內存中數據更新、查詢快,極大縮短了操做響應時間;二是內存中元數據丟失風險頗高(斷電等),所以輔佐元數據鏡像文件(fsimage)+編輯日誌文件(edits)的備份機制進行確保元數據的安全。
NameNode 維護整個文件系統元數據。所以,元數據的準確管理,影響着 HDFS 提供文件存儲服務的能力。
在 Hadoop 的 HDFS 首次部署好配置文件以後,並不能立刻啓動使用,而是先要對文件系統進行格式化。須要在 NameNode(NN)節點上進行以下的操做:
$HADOOP_HOME/bin/hdfs namenode –format
在這裏要注意兩個概念,一個是文件系統,此時的文件系統在物理上還不存在;二就是此處的格式化並非指傳統意義上的本地磁盤格式化,而是一些清除與準備工做。
格式化完成以後,將會在$dfs.namenode.name.dir/current 目錄下建立以下的文件結構,這個目錄也正是 namenode 元數據相關的文件目錄:
其中的 dfs.namenode.name.dir 是在 hdfs-site.xml 文件中配置的,默認值以下:
dfs.namenode.name.dir 屬性能夠配置多個目錄,各個目錄存儲的文件結構和內容都徹底同樣,至關於備份,這樣作的好處是當其中一個目錄損壞了,也不會影響到 Hadoop 的元數據,特別是當其中一個目錄是 NFS(網絡文件系統 Network File System,NFS)之上,即便你這臺機器損壞了,元數據也獲得保存。
下面對$dfs.namenode.name.dir/current/目錄下的文件進行解釋。
VERSION
namespaceID=934548976
clusterID=CID-cdff7d73-93cd-4783-9399-0a22e6dce196
cTime=0
storageType=NAME_NODE
blockpoolID=BP-893790215-192.168.24.72-1383809616115
layoutVersion=-47
namespaceID/clusterID/blockpoolID 這些都是 HDFS 集羣的惟一標識符。標識符被用來防止 DataNodes 意外註冊到另外一個集羣中的 namenode 上。這些標識在聯邦(federation)部署中特別重要。聯邦模式下,會有多個 NameNode 獨立工做。每一個的 NameNode 提供惟一的命名空間(namespaceID),並管理一組惟一的文件塊池(blockpoolID)。clusterID 將整個集羣結合在一塊兒做爲單個邏輯單元,在集羣中的全部節點上都是同樣的。
storageType 說明這個文件存儲的是什麼進程的數據結構信息(若是是 DataNode,storageType=DATA_NODE);
cTime NameNode 存儲系統建立時間,首次格式化文件系統這個屬性是 0,當文件系統升級以後,該值會更新到升級以後的時間戳;
layoutVersion 表示 HDFS 永久性數據結構的版本信息,是一個負整數。
補充說明:
格式化集羣的時候,能夠指定集羣的 cluster_id,可是不能與環境中其餘集羣有衝突。
若是沒有提供 cluster_id,則會自動生成一個惟一的 ClusterID。
$HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>
seen_txid
$dfs.namenode.name.dir/current/seen_txid 很是重要,是存放 transactionId 的文件,format 以後是 0,它表明的是 namenode 裏面的 edits_*文件的尾數,namenode 重啓的時候,會按照 seen_txid 的數字,循序從頭跑 edits_0000001~到 seen_txid 的數字。因此當你的 hdfs 發生異常重啓的時候,必定要比對 seen_txid 內的數字是否是你 edits 最後的尾數。
Fsimage & edits
$dfs.namenode.name.dir/current 目錄下在 format 的同時也會生成 fsimage 和 edits文件,及其對應的 md5 校驗文件。
NameNode 職責是管理元數據信息,DataNode 的職責是負責數據具體存儲,那麼SecondaryNameNode 的做用是什麼?對不少初學者來講是很是迷惑的。它爲何會出如今HDFS 中。從它的名字上看,它給人的感受就像是 NameNode 的備份。但它實際上卻不是。
你們猜測一下,當 HDFS 集羣運行一段事件後,就會出現下面一些問題:
edit logs 文件會變的很大,怎麼去管理這個文件是一個挑戰。
NameNode 重啓會花費很長時間,由於有不少改動要合併到 fsimage 文件上。
若是 NameNode 掛掉了,那就丟失了一些改動。由於此時的 fsimage 文件很是舊。
所以爲了克服這個問題,咱們須要一個易於管理的機制來幫助咱們 減少 s edit logs 文件的大小和獲得一個最新的fsimage 文件,這樣也會減少在 NameNode 上的壓力。這跟Windows 的恢復點是很是像的,Windows 的恢復點機制容許咱們對 OS 進行快照,這樣當系統發生問題時,咱們可以回滾到最新的一次恢復點上。
SecondaryNameNode 就是來幫助解決上述問題的,它的職責是合併 NameNode 的 editlogs 到 fsimage 文件中。
每達到觸發條件,會由 secondary namenode 將 namenode 上積累的全部 edits 和一個最新的 fsimage 下載到本地,並加載到內存進行 merge(這個過程稱爲 checkpoint),以下圖所示:
Checkpoint 操做受兩個參數控制,能夠經過 core-site.xml 進行配置:
<property> <name> dfs.namenode.checkpoint.period</name> <value>3600</value> <description> 兩次連續的 checkpoint 之間的時間間隔。默認 1 小時 </description> </property> <property> <name>dfs.namenode.checkpoint.txns</name> <value>1000000</value> <description> 最大的沒有執行 checkpoint 事務的數量,知足將強制執行緊急 checkpoint,即便 還沒有達到檢查點週期。默認設置爲 100 萬。 </description> </property>
從上面的描述咱們能夠看出,SecondaryNamenode 根本就不是 Namenode 的一個熱備,其只是將 fsimage 和 edits 合併。其擁有的 fsimage 不是最新的,由於在他從 NameNode 下載 fsimage 和 edits 文件時候,新的更新操做已經寫到 edit.new 文件中去了。而這些更新在 SecondaryNamenode 是沒有同步到的!固然, 若是 NameNode 中的 fsimage 真的出問題了,仍是能夠用SecondaryNamenode 中的 fsimage 替換一下NameNode 上的 fsimage ,雖然已經不是最新的 fsimage ,可是咱們能夠將損失減少到最少!