Hadoop入門(二)之 HDFS 詳細解析

PeTu發表於2018-09-11

原文地址:pengtuo.tech/2018/09/10/…

Hadoop 生態是一個龐大的、功能齊全的生態,但是圍繞的還是名為 Hadoop 的分散式系統基礎架構,其核心元件由四個部分組成,分別是:CommonHDFSMapReduce 以及 YARN

  1. CommonHadoop 架構的通用元件;
  2. HDFSHadoop 的分散式檔案儲存系統;
  3. MapReduceHadoop 提供的一種程式設計模型,可用於大規模資料集的並行運算;
  4. YARNHadoop 架構升級後,目前廣泛使用的資源管理器。

小目標是為每一個核心元件寫一篇全解的博文,本篇先來好好了解下 HDFS

一、介紹

HDFS(The Hadoop Distributed File System),是被設計成適合執行在通用硬體(commodity hardware)上的 Hadoop 的分散式檔案系統。它與其他的分散式系統有非常顯著的不同,首先 HDFS 具有高容錯性,並且它可以被部署到廉價的硬體上。此外,HDFS 提供對應用程式資料的高吞吐量訪問,適用於具有大型資料集的應用程式。

目前,HDFS 作為 Apache Hadoop 的核心專案,URL為:hadoop.apache.org/

二、HDFS 優點

2.1 硬體故障防治

一個 HDFS 例項有可能包含數百臺或數千臺伺服器,每一個臺機器都儲存檔案系統資料的一部分,這種情況下硬體故障是常態。而 HDFS 可檢測故障並從中快速自動恢復。

2.2 流資料訪問

HDFS 設計用於批處理而不是使用者的互動式使用,其重點是資料訪問的高吞吐量而並不追求資料訪問的低延遲。

2.3 處理大資料集

HDFS 的核心目標就是為處理具有大資料量的應用,在其上執行的應用的檔案大小一般都為 TB 級別。HDFS 可提供高聚合資料頻寬並且要擴充套件到叢集中的數百個節點上,並對於單個應用可支援上千萬個檔案。

2.4 簡單一致模型

HDFS 應用程式是一個"一次寫入多次讀取"的檔案訪問模型。這種模型可以簡化資料的一致性問題並且能夠實現高吞吐資料訪問。官方文件表示有計劃支援追加寫入檔案的功能。

2.5 移動計算替代移動資料

“Moving Computation is Cheaper than Moving Data”,當一個計算程式與資料同在一個物理節點上時,運算最高效,特別是當資料量特別大時,移動計算遠優於移動資料集。移動計算可以最大限度地減少網路擁塞並提高系統的整體吞吐量。HDFS 設計的是將計算遷移到更靠近資料所在的位置,而不是將資料移動到執行應用程式的位置。HDFS 為應用程式提供了介面,使其自身更靠近資料。

2.6 跨異構硬體和軟體平臺的可移植性

HDFS 的設計便於從一個平臺移植到另一個平臺。 這有助於廣泛採用 HDFS 作為大量應用程式的首選大資料處理平臺。

三、NameNode & DataNodes

NameNodeDataNodeHDFS 系統的重要知識點。HDFSmaster/slave 體系結構。一個 HDFS 叢集是由單個 NameNode 和眾多 DataNode 組成,檔案會被分成一個或多個塊,這些塊儲存在一組 DataNode 中。

因為 HDFS 是用 Java 語言搭建的,所以只要是支援 Java 語言的機器都可以執行 NameNodeDataNode。並且因為 Java 的高可移植性,HDFS 也具有非常廣泛的應用範圍。一種典型的 HDFS 部署模式是指定一個物理主機執行 NameNode,然後其餘的機器執行 DataNode,在實際部署情況中,一般都是一臺主機部署一個 DataNode

群集中存在單個 NameNode 極大地簡化了系統的體系結構。 NameNode 是所有 HDFS 後設資料的決定者和儲存庫。系統的這種設計使使用者資料永遠不會流經 NameNode,可理解 NameNode 為整個系統的中樞。

架構如下圖:

image

首先圖中的 rack 翻譯為“機架”,可以理解為兩個處於不同地方的機群,每個機群內部有自己的連線方式。其次在 DataNode 中儲存的不是當個檔案,而是檔案塊(Block),在 HDFS 中,每個大檔案會拆分成多個 Block,然後將這些 Block 散佈儲存在不同的 DataNode 中,並且每個 Block 會有多個複製,也會儲存到其他的 DataNode中。

可以看出上圖分別解釋了“讀”和“寫”兩種操作:

  1. 當有客戶端要向 HDFS 寫入檔案時,圖中將檔案拆分的 Block 寫入到了兩個機架的 DataNode 中,一般情況下就是兩個機架的兩個物理主機中,可以看出檔案資料沒有經過 NameNode。資料寫入的過程見(“七、資料複製流水線”)
  2. 當有客戶端要從 HDFS 讀取檔案時,會將操作命令傳向 NameNode,然後 NameNode 轉為對應的資料塊的操作,指揮相應的 DataNode 將所需資料返回給客戶端。

還有一個節點圖中沒有顯示,叫作 Secondary Namenode,是輔助後臺程式,主要負責與 NameNode 進行通訊,定期儲存 HDFS 後設資料的快照及備份其他 NameNode 中的內容,日常 Standby,當 NameNode 故障時頂替 NameNode 使用。

NameNode

NameNode 是管理檔案系統名稱空間的主伺服器,用於管理客戶端對檔案的訪問,執行檔案系統名稱空間操作,如開啟,關閉和重新命名檔案和目錄。它還確定了BlockDataNode 的對映。

NameNode 做著有關塊複製的所有決定,它定期從群集中的每個 DataNode 接收 HeartbeatBlockreport。收到 Heartbeat 意味著 DataNode正常執行,Blockreport 包含 DataNode 上所有塊的列表。

DataNode

DataNode 通常是群集中每個節點一個,用於儲存資料,負責提供來自檔案系統客戶端的讀寫請求。並且還會根據 NameNode 的指令執行塊建立,刪除和複製。

四、HDFS檔案系統名稱空間及後設資料

HDFS 支援傳統的分層檔案組織,檔案系統名稱空間層次結構與大多數其他現有檔案系統類似,一個使用者或者應用可以建立資料夾並且在這個資料夾裡儲存檔案。但是 HDFS 不支援 Linux 裡的硬連結和軟連線。NameNode 維護著檔案系統的名稱空間,其記錄對檔案系統名稱空間或其屬性的任何更改,NameNode 還會儲存複製因子。

資料塊的副本數稱為該資料塊的複製因子

檔案系統的後設資料(MetaData)也儲存在 NameNode 中,NameNode 使用名為 EditLog 的事務日誌來持久記錄檔案系統後設資料發生的每個更改。例如,在 HDFS 中建立新檔案會導致 NameNode 將記錄插入 EditLog,以指示此情況。NameNode 使用其本地主機OS檔案系統中的檔案來儲存 EditLog

而整個檔案系統名稱空間(包括塊到檔案和檔案系統屬性的對映)儲存在名為 FsImage 的檔案中。 FsImage 也作為檔案儲存在 NameNode 的本地檔案系統中。

後設資料的持久化

NameNode 在整個記憶體中儲存整個檔案系統名稱空間和檔案的資料塊對映。當 NameNode 啟動,或者檢查點由可配置的閾值觸發時,它從磁碟讀取 FsImageEditLog,並先將 FsImage 中的檔案系統後設資料資訊載入到記憶體,然後把 EditLog 中的所有事務應用到記憶體中的 FsImage,最後將此新版本同步到磁碟上的 FsImage。然後它可以截斷舊的 EditLog,因為它的事務已應用於永續性 FsImage。此過程稱為檢查點。

檢查點的目的是通過獲取檔案系統後設資料的快照並將其儲存到 FsImage 來確保 HDFS 具有檔案系統後設資料的一致檢視。儘管直接從記憶體中讀取 FsImage 很高效,但直接對 FsImage 進行增量編輯效率不高。我們不會修改每個編輯的 FsImage,而是在 Editlog 中保留編輯內容。

在檢查點期間,Editlog 的更改將應用於 FsImage。可以以秒為單位的給定時間間隔(dfs.namenode.checkpoint.period)觸發檢查點,或者在累積給定數量的檔案系統事務(dfs.namenode.checkpoint.txns)之後觸發檢查點。如果同時設定了這兩個屬性,則一旦滿足其中一個閾值就可觸發檢查點。

五、資料複製(Data Replication)

HDFS 旨在跨大型叢集中的計算機可靠地儲存非常大的檔案。它將每個檔案儲存為一系列塊,除最後一個塊之外的檔案中的所有塊都具有相同的大小,HDFS 使用的預設塊大小為 128MB。複製檔案的塊以實現容錯,且一般複製出的檔案塊會儲存到不同的 DataNode 中。資料塊的大小以及複製因子都是可以由使用者設定。

HDFS中的檔案是一次寫入的,並且在任何時候都只能有一個寫入器。

image

解釋:如圖所示,part-0 檔案複製因子為r:2,其拆分的資料塊號有{1,3},所以 1 號資料塊在第1,第3個 DataNode 上,3 號資料塊在第5,第6個DataNode上;part-1檔案解釋同理。而這些資訊都儲存在 NameNode 中。

HDFS 副本存放策略

剛剛只是簡單的介紹了圖裡的資訊,實際 HDFS 副本放置策略是一個值得研究的課題,因為這切實關係到 HDFS 的可依賴性與表現,並且經過優化的副本放置策略也使得 HDFS 相比其他分散式檔案系統具有優勢。

在大部分的實際案例中,當複製因子是 r = 3 時,HDFS 的放置策略是將一個複製品放置到寫入器操作的 DataNode中,第二個複製品放置到另一個遠端機架上的一個節點中,然後最後一個複製品則放置同一個遠端機架的不同物理節點中。

這種放置策略可以有效的減少機架之中的通訊以提高系統的表現。因為不同機架的物理節點的通訊需要通過交換機,而在大多數情況下,同一機架中的計算機之間的網路頻寬大於不同機架中的計算機之間的網路頻寬。

如果複製因子大於3,則隨機確定第4個及以後副本的放置,同時保持每個機架的副本數量低於上限。

上限數一般為(副本數-1)/ 機架 + 2

由於 NameNode 不允許 DataNode 具有同一塊的多個副本,因此,能建立的最大副本數是此時 DataNode 的總數。

當有客戶端請求讀取時,HDFS 為了最小化全域性頻寬消耗與讀取延遲,會優先選擇離讀取客戶端最近的資料副本。

六、通訊協議

所有 HDFS 通訊協議都分層在 TCP/IP 協議之上。

七、資料複製流水線

當客戶端將資料寫入複製因子為 r = 3HDFS 檔案時,NameNode 使用 replication target choosing algorithm 檢索 DataNode 列表。此列表包含將承載該塊副本的 DataNode

然後客戶端向第一個 DataNode 寫入,第一個 DataNode 開始分批接收資料,將每個部分寫入其本地儲存,並將該部分傳輸到列表中的第二個 DataNode。第二個 DataNode 又開始接收資料塊的每個部分,將該部分寫入其儲存,然後將該部分重新整理到第三個 DataNode。最後,第三個 DataNode 將資料寫入其本地儲存。

可見,DataNode 是從流水線中的前一個接收資料,同時將資料轉發到流水線中的下一個,資料是從一個 DataNode 流水線到下一個 DataNode

八、可操作

應用可以以多種方式操控 HDFS 上的檔案,其中通過 FS Shell 可以像操控 Linux 檔案系統一般,常用命令有:

Action Command
建立 foodir 資料夾 bin/hadoop fs -mkdir /foodir
刪除資料夾 bin/hadoop fs -rm -R /foodir
檢視檔案內容 bin/hdfs dfs -cat /foodir/myfile.txt
上傳檔案 bin/hdfs dfs -copyFromLocal ~/a.txt /foodir/
…… ……

會發現這裡有兩種命令字首,一個是 hadoop fs,一個是 hdfs dfs

區別是:hadoop fs 可以用於其他檔案系統,不止是hdfs檔案系統內,也就是說該命令的使用範圍更廣;而 hdfs dfs 專門針對hdfs分散式檔案系統。

還有一個字首為 hadoop dfs,這個已經過時,建議不要使用?。

九、空間回收

9.1 檔案刪除和取消刪除

如果啟用了垃圾箱配置,則 FS Shell 刪除的檔案不會立即從 HDFS 中刪除,而是 HDFS 將其移動到垃圾目錄(/user/username/.Trash)。

在垃圾箱中,被刪除檔案的生命週期到期後,NameNode 將從 HDFS 名稱空間中刪除該檔案。刪除檔案會導致釋放與檔案關聯的塊。

注意:在使用者刪除檔案的時間與 HDFS 中相應增加的可用空間之間可能存在明顯的時間延遲。

如果啟用了垃圾箱配置,想直接徹底刪除,命令為:hadoop fs -rm -r -skipTrash a.txt

9.2 減少複製因子

當檔案的複製因子減少時,NameNode 選擇可以刪除的多餘副本。下一個 Heartbeat 將此資訊傳輸到 DataNode。然後,DataNode刪除相應的塊,並在群集中顯示相應的可用空間。

參考

[1] Hadoop JavaDoc API

[2] HDFS 原始碼: hadoop.apache.org/version_con…

[3] HDFS 文件: hadoop.apache.org/docs/stable…

相關文章