前方高能 | HDFS 的架構,你吃透了嗎?

語言: CN / TW / HK

前言

HDFS 是 Hadoop 中儲存資料的基石,儲存著所有的資料,具有 高可靠 性,高容錯性,高可擴充套件性,高吞吐量  等特徵,能夠部署在大規模廉價的叢集上,極大地降低了部署成本。有意思的是, 其良好的架構特徵使其能夠儲存海量的資料 。本篇文章,我們就來系統學習一下,Hadoop HDFS的架構!

HDFS架構

HDFS採用 Master/Slave 架構儲存資料,且支援 NameNode 的 HA。HDFS架構主要包含客戶端, NameNodeSecondaryNameNodeDataNode 四個重要組成部分,如圖所示:

(1)客戶端向NameNode 發起請求 ,獲取元資料資訊,這些元資料資訊包括名稱空間、塊對映資訊及 DataNode 的位置資訊等。

(2)NameNode 將元資料資訊 返回 給客戶端。

(3)客戶端獲取到元資料資訊後,到相應的 DataNode 上 讀/寫資料

(4)相關聯的 DataNode 之間會 相互複製資料 ,以達到 DataNode 副本數的要求

(5)DataNode 會 定期 向 NameNode 傳送心跳資訊,將自身節點的狀態資訊報告給 NameNode。

(6)SecondaryNameNode 並不是 NameNode 的備份。SecondaryNameNode 會定期獲取 NameNode 上的 fsimageedits log 日誌,並將二者進行合併,產生 fsimage.ckpt 推送給 NameNode。

1、NameNode

NameNode 是整個 Hadooop 叢集中至關重要的元件,它維護著整個 HDFS 樹,以及檔案系統樹中所有的檔案和檔案路徑的元資料資訊 。這些元資料資訊包括 檔名命令空間檔案屬性 (檔案生成的時間、檔案的副本數、檔案的許可權)、 檔案資料塊檔案資料塊與所在 DataNode 之間的對映關係 等。

一旦 NameNode 宕機或 NameNode 上的元資料資訊損壞或丟失,基本上就會丟失 Hadoop 叢集中儲存的所有資料,整個 Hadoop 叢集也會隨之癱瘓

在 Hadoop 執行的過程中, NameNode 的主要功能如下圖所示:

2、SecondaryNameNode

SecondaryNameNode 並不是 NameNode 的備份,在NameNode 發生故障時也不能立刻接管 NameNode 的工作 。SecondaryNameNode 在 Hadoop 執行的過程中具有兩個作用:一個是 備份資料映象 ,另一個是 定期合併日誌與映象 ,因此可以稱其為 Hadoop 的 檢查點 (checkpoint)。 SecondaryNameNode 定期合併 NameNode 中的 fsimage 和 edits log,能夠防止 NameNode 重啟時把整個 fsimage 映象檔案載入到記憶體,耗費過長的啟動時間

SecondaryNameNode 的工作流程如圖所示:

SecondaryNameNode的工作流程如下:

(1)SecondaryNameNode 會 通知 NameNode 生成 新的 edits log 日誌檔案。

(2)NameNode 生成 新的 edits log 日誌檔案,然後將新的日誌資訊 寫到 新生成的 edits log 日誌檔案中。

(3)SecondaryNameNode 複製 NameNode 上的 fsimage 映象和 edits log 日誌檔案,此時使用的是 http get 方式。

(4)SecondaryNameNode 將fsimage將映象檔案 載入 到記憶體中,然後執行 edits log 日誌檔案中的操作, 生成 新的映象檔案 fsimage.ckpt。

(5)SecondaryNameNode 將 fsimage.ckpt 檔案 傳送 給 NameNode,此時使用的是 http post 方式。

(6)NameNode 將 edits log 日誌檔案 替換 成新生成的 edits.log 日誌檔案,同樣將 fsimage檔案 替換 成 SecondaryNameNode 傳送過來的新的 fsimage 檔案。

(7)NameNode 更新 fsimage 檔案,將此次執行 checkpoint 的時間 寫入 fstime 檔案中。

經過 SecondaryNameNode 對 fsimage 映象檔案和 edits log 日誌檔案的 複製和合並 操作之後,NameNode 中的 fsimage 映象檔案就 儲存 了最新的 checkpoint 的元資料資訊, edits log 日誌檔案也會重新 寫入 資料,兩個檔案中的資料不會變得很大。因此,當  重啟 NameNode 時,不會耗費太長的啟動時間

SecondaryNameNode 週期性地進行 checkpoint 操作需要滿足一定的前提條件,這些條件如下:

(1) edits log 日誌檔案的大小達到了一定的閾值,此時會對其進行合併操作。

(2)每隔一段時間進行 checkpoint 操作。

這些條件可以在 core-site.xml 檔案中進行配置和調整,程式碼如下所示:

<property>
<name>fs.checkpoint.period</name>
<value>3600</value>
</property>
<property>
<name>fs.checkpoint.size</name>
<value>67108864</value>
</property>

上述程式碼配置了 checkpoint 發生的時間週期和 edits log  日誌檔案的大小閾值,說明如下。

(1) fs.checkpoint.period :表示觸發 checkpoint 發生的時間週期,這裡配置的時間週期為 1 h。

(2) fs.checkpoint.size :表示 edits log 日誌檔案大小達到了多大的閾值時會發生 checkpoint 操作,這裡配置的 edits log 大小閾值為 64 MB。

上述程式碼中配置的 checkpoint 操作發生的情況如下:

(1)如果 edits log 日誌檔案經過 1 h 未能達到 64 MB,但是滿足了 checkpoint 發生的週期為 1 h 的條件,也會發生 checkpoint 操作。

(2)如果 edits log  日誌檔案大小在 1 h 之內達到了 64MB,滿足了 checkpoint 發生的 edits log  日誌檔案大小閾值的條件,則會發生 checkpoint  操作。

注意:如果 NameNode 發生故障或 NameNode 上的元資料資訊丟失或損壞導致 NameNode 無法啟動,此時就需要 人工干預 ,將 NameNode 中的元資料狀態恢復到 SecondaryNameNode 中的 元資料 狀態。此時,如果 SecondaryNameNode 上的元資料資訊與 NameNode 宕機時的元資料資訊不同步,則或多或少地會導致 Hadoop 叢集中丟失一部分資料。出於此原因, 應儘量避免將 NameNode 和 SecondaryNameNode 部署在同一臺伺服器

3、DataNode

DataNode 是真正儲存資料的節點 ,這些資料以 資料塊 的形式儲存在 DataNode 上。一個數據塊包含兩個檔案:一個是 儲存資料本身的檔案 ,另一個是 儲存元資料的檔案 (這些元資料主要包括 資料塊的長度資料塊的檢驗和時間戳 )。

DataNode 執行時的 工作機制 如圖所示:

如圖所示,DataNode 執行時的工作機制如下:

(1)DataNode啟動之後,向 NameNode 註冊

(2)NameNode 返回 註冊成功的訊息給 DataNode。

(3)DataNode 收到 NameNode 返回的註冊成功的資訊之後,會 週期性 地向 NameNode 上報 當前 DataNode 的所有塊資訊,預設傳送所有資料塊的時間週期是 1h

(4)DataNode 週期性 地向NameNode 傳送心跳資訊;NameNode 收到 DataNode 發來的心跳資訊後,會將DataNode 需要執行的命令放入到 心跳資訊 的 返回資料中, 返回 給 DataNode。DataNode 向 NameNode 傳送心跳資訊的預設時間週期是 3s

(5)NameNode 超過一定的時間 沒有收到 DataNode 發來的心跳資訊,則 NameNode 會認為對應的 DataNode 不可用 。預設的超時時間是 10 min

(6)在儲存上相互關聯的 DataNode 會同步資料塊,以達到資料副本數的要求。

當 DataNode 發生故障導致 DataNode 無法與 NameNode 通訊時,NameNode 不會立即認為 DataNode 已經 “死亡”。要經過一段 短暫的超時時長 後才會認為 DataNode 已經 “死亡”。HDFS 中預設的超時時長為 10 min + 30 s,可以用如下公式來表示這個超時時長:

timeout = 2 * dfs.namenode.heartbeat.recheck-interval +10 * dfs.heartbeat.interval

其中,各引數的含義如下:

(1) timeout :超時時長。

(2) dfs.namenode.heartbeat.recheck-interval :檢查過期 DataNode 的時間間隔,與 dfs.heartbeat.interval 結合使用,預設的單位是 ms,預設時間是 5 min

(3) dfs.heartbeat.interval :檢測資料節點的時間間隔,預設的單位為 s,預設的時間是 3 s

所以,可以得出 DataNode 的預設超時時長為 630s ,如下所示:

timeout = 2 * 5 * 60 + 10 * 3 = 630s

DataNode 的超時時長也可以在 hdfs-site.xml 檔案中進行配置,程式碼如下所示:

<property>
<name>dfs.namenode.heartbeat.recheck-interval</name>
<value>3000</value>
</property>
<property>
<name>dfs.heartbeat.interval</name>
<value>2</value>
</property>

根據上面的公式可以得出,在配置檔案中配置的超時時長為:

timeout = 2 * 3000 / 1000 + 10 * 2 = 26s

當 DataNode 被 NameNode 判定為 “ 死亡 ”時,HDFS 就會馬上自動進行 資料塊的容錯複製 。此時,當被 NameNode 判定為 “死亡” 的 DataNode 重新加入叢集中時,如果其儲存的資料塊並沒有損壞,就會造成 HDFS 上某些資料塊的備份數超過系統配置的備份數目

HDFS上 刪除多餘的資料塊 需要的時間長短和資料塊報告的時間間隔有關。該引數可以在 hdfs-site.xml 檔案中進行配置,程式碼如下所示:

<property>
<name>dfs.blockreport.intervalMsec</name>
<value>21600000</value>
<description>Determines block reporting interval in milliseconds.</description>
</property>

資料塊報告的時間間隔預設為 21600000 ms,即 6h,可以通過調整此引數的大小來調整資料塊報告的時間間隔。

小結

本篇文章算是對 HDFS的架構 解釋的比較透徹,相信不論是剛入門的小白,還是已經有了一定基礎的大資料學者,看完都會有一定的收穫,希望大家平時學習也能夠多學會總結, 用輸出倒逼自己輸入 !        

巨人的肩膀

1、《海量資料處理與大資料技術實戰》 
2、《大資料平臺架構與原型實現》 
3、https://baike.baidu.com/item/hdfs/4836121?fr=aladdin
 4、http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_user_guide.html

· · · · · · · · · · · · · · · · · E N D · · · · · · · · · · · · · · · ·