Hadoop
生態(tài)是一個龐大的、功能齊全的生態(tài),但是圍繞的還是名為 Hadoop
的分布式系統(tǒng)基礎(chǔ)架構(gòu),其核心組件由四個部分組成,分別是:Common
、HDFS
、MapReduce
以及 YARN
。
-
Common
是Hadoop
架構(gòu)的通用組件; -
HDFS
是Hadoop
的分布式文件存儲系統(tǒng); -
MapReduce
是Hadoop
提供的一種編程模型,可用于大規(guī)模數(shù)據(jù)集的并行運算; -
YARN
是Hadoop
架構(gòu)升級后,目前廣泛使用的資源管理器。
小目標(biāo)是為每一個核心組件寫一篇全解的博文,本篇先來好好了解下 HDFS
。
一、介紹
HDFS(The Hadoop Distributed File System),是被設(shè)計成適合運行在通用硬件(commodity hardware
)上的 Hadoop
的分布式文件系統(tǒng)。它與其他的分布式系統(tǒng)有非常顯著的不同,首先 HDFS
具有高容錯性,并且它可以被部署到廉價的硬件上。此外,HDFS
提供對應(yīng)用程序數(shù)據(jù)的高吞吐量訪問,適用于具有大型數(shù)據(jù)集的應(yīng)用程序。
目前,HDFS
作為 Apache Hadoop
的核心項目,URL為:http://hadoop.apache.org/
二、HDFS 優(yōu)點
2.1 硬件故障防治
一個 HDFS
實例有可能包含數(shù)百臺或數(shù)千臺服務(wù)器,每一個臺機(jī)器都存儲文件系統(tǒng)數(shù)據(jù)的一部分,這種情況下硬件故障是常態(tài)。而 HDFS
可檢測故障并從中快速自動恢復(fù)。
2.2 流數(shù)據(jù)訪問
HDFS
設(shè)計用于批處理而不是用戶的交互式使用,其重點是數(shù)據(jù)訪問的高吞吐量而并不追求數(shù)據(jù)訪問的低延遲。
2.3 處理大數(shù)據(jù)集
HDFS
的核心目標(biāo)就是為處理具有大數(shù)據(jù)量的應(yīng)用,在其上運行的應(yīng)用的文件大小一般都為 TB
級別。HDFS
可提供高聚合數(shù)據(jù)帶寬并且要擴(kuò)展到集群中的數(shù)百個節(jié)點上,并對于單個應(yīng)用可支持上千萬個文件。
2.4 簡單一致模型
HDFS
應(yīng)用程序是一個"一次寫入多次讀取"的文件訪問模型。這種模型可以簡化數(shù)據(jù)的一致性問題并且能夠?qū)崿F(xiàn)高吞吐數(shù)據(jù)訪問。官方文檔表示有計劃支持追加寫入文件的功能。
2.5 移動計算替代移動數(shù)據(jù)
“Moving Computation is Cheaper than Moving Data”,當(dāng)一個計算程序與數(shù)據(jù)同在一個物理節(jié)點上時,運算最高效,特別是當(dāng)數(shù)據(jù)量特別大時,移動計算遠(yuǎn)優(yōu)于移動數(shù)據(jù)集。移動計算可以最大限度地減少網(wǎng)絡(luò)擁塞并提高系統(tǒng)的整體吞吐量。HDFS
設(shè)計的是將計算遷移到更靠近數(shù)據(jù)所在的位置,而不是將數(shù)據(jù)移動到運行應(yīng)用程序的位置。HDFS
為應(yīng)用程序提供了接口,使其自身更靠近數(shù)據(jù)。
2.6 跨異構(gòu)硬件和軟件平臺的可移植性
HDFS
的設(shè)計便于從一個平臺移植到另一個平臺。 這有助于廣泛采用 HDFS
作為大量應(yīng)用程序的首選大數(shù)據(jù)處理平臺。
三、NameNode & DataNodes
NameNode
與 DataNode
是 HDFS
系統(tǒng)的重要知識點。HDFS
是 master/slave
體系結(jié)構(gòu)。一個 HDFS
集群是由單個 NameNode
和眾多 DataNode
組成,文件會被分成一個或多個塊,這些塊存儲在一組 DataNode
中。
因為 HDFS
是用 Java 語言搭建的,所以只要是支持 Java 語言的機(jī)器都可以運行 NameNode
和 DataNode
。并且因為 Java 的高可移植性,HDFS
也具有非常廣泛的應(yīng)用范圍。一種典型的 HDFS
部署模式是指定一個物理主機(jī)運行 NameNode
,然后其余的機(jī)器運行 DataNode
,在實際部署情況中,一般都是一臺主機(jī)部署一個 DataNode
。
群集中存在單個 NameNode
極大地簡化了系統(tǒng)的體系結(jié)構(gòu)。 NameNode
是所有 HDFS
元數(shù)據(jù)的決定者和存儲庫。系統(tǒng)的這種設(shè)計使用戶數(shù)據(jù)永遠(yuǎn)不會流經(jīng) NameNode
,可理解 NameNode
為整個系統(tǒng)的中樞。
架構(gòu)如下圖:
首先圖中的 rack
翻譯為“機(jī)架”,可以理解為兩個處于不同地方的機(jī)群,每個機(jī)群內(nèi)部有自己的連接方式。其次在 DataNode
中存儲的不是當(dāng)個文件,而是文件塊(Block),在 HDFS
中,每個大文件會拆分成多個 Block
,然后將這些 Block
散布存儲在不同的 DataNode
中,并且每個 Block
會有多個復(fù)制,也會存儲到其他的 DataNode
中。
可以看出上圖分別解釋了“讀”和“寫”兩種操作:
- 當(dāng)有客戶端要向
HDFS
寫入文件時,圖中將文件拆分的Block
寫入到了兩個機(jī)架的DataNode
中,一般情況下就是兩個機(jī)架的兩個物理主機(jī)中,可以看出文件數(shù)據(jù)沒有經(jīng)過NameNode
。數(shù)據(jù)寫入的過程見(“七、數(shù)據(jù)復(fù)制流水線”) - 當(dāng)有客戶端要從
HDFS
讀取文件時,會將操作命令傳向NameNode
,然后NameNode
轉(zhuǎn)為對應(yīng)的數(shù)據(jù)塊的操作,指揮相應(yīng)的DataNode
將所需數(shù)據(jù)返回給客戶端。
還有一個節(jié)點圖中沒有顯示,叫作
Secondary Namenode
,是輔助后臺程序,主要負(fù)責(zé)與NameNode
進(jìn)行通信,定期保存HDFS
元數(shù)據(jù)的快照及備份其他NameNode
中的內(nèi)容,日常Standby
,當(dāng)NameNode
故障時頂替NameNode
使用。
NameNode
NameNode
是管理文件系統(tǒng)命名空間的主服務(wù)器,用于管理客戶端對文件的訪問,執(zhí)行文件系統(tǒng)命名空間操作,如打開,關(guān)閉和重命名文件和目錄。它還確定了Block
到 DataNode
的映射。
NameNode
做著有關(guān)塊復(fù)制的所有決定,它定期從群集中的每個 DataNode
接收 Heartbeat
和 Blockreport
。收到 Heartbeat
意味著 DataNode
正常運行,Blockreport
包含 DataNode
上所有塊的列表。
DataNode
DataNode
通常是群集中每個節(jié)點一個,用于存儲數(shù)據(jù),負(fù)責(zé)提供來自文件系統(tǒng)客戶端的讀寫請求。并且還會根據(jù) NameNode
的指令執(zhí)行塊創(chuàng)建,刪除和復(fù)制。
四、HDFS文件系統(tǒng)命名空間及元數(shù)據(jù)
HDFS
支持傳統(tǒng)的分層文件組織,文件系統(tǒng)命名空間層次結(jié)構(gòu)與大多數(shù)其他現(xiàn)有文件系統(tǒng)類似,一個用戶或者應(yīng)用可以創(chuàng)建文件夾并且在這個文件夾里存儲文件。但是 HDFS
不支持 Linux 里的硬鏈接和軟連接。NameNode
維護(hù)著文件系統(tǒng)的命名空間,其記錄對文件系統(tǒng)命名空間或其屬性的任何更改,NameNode
還會存儲復(fù)制因子。
數(shù)據(jù)塊的副本數(shù)稱為該數(shù)據(jù)塊的復(fù)制因子
文件系統(tǒng)的元數(shù)據(jù)(MetaData
)也存儲在 NameNode
中,NameNode
使用名為 EditLog
的事務(wù)日志來持久記錄文件系統(tǒng)元數(shù)據(jù)發(fā)生的每個更改。例如,在 HDFS
中創(chuàng)建新文件會導(dǎo)致 NameNode
將記錄插入 EditLog
,以指示此情況。NameNode
使用其本地主機(jī)OS文件系統(tǒng)中的文件來存儲 EditLog
。
而整個文件系統(tǒng)命名空間(包括塊到文件和文件系統(tǒng)屬性的映射)存儲在名為 FsImage
的文件中。 FsImage
也作為文件存儲在 NameNode
的本地文件系統(tǒng)中。
元數(shù)據(jù)的持久化
NameNode
在整個內(nèi)存中保存整個文件系統(tǒng)命名空間和文件的數(shù)據(jù)塊映射。當(dāng) NameNode
啟動,或者檢查點由可配置的閾值觸發(fā)時,它從磁盤讀取 FsImage
和 EditLog
,并先將 FsImage
中的文件系統(tǒng)元數(shù)據(jù)信息加載到內(nèi)存,然后把 EditLog
中的所有事務(wù)應(yīng)用到內(nèi)存中的 FsImage
,最后將此新版本同步到磁盤上的 FsImage
。然后它可以截斷舊的 EditLog
,因為它的事務(wù)已應(yīng)用于持久性 FsImage
。此過程稱為檢查點。
檢查點的目的是通過獲取文件系統(tǒng)元數(shù)據(jù)的快照并將其保存到 FsImage
來確保 HDFS
具有文件系統(tǒng)元數(shù)據(jù)的一致視圖。盡管直接從內(nèi)存中讀取 FsImage
很高效,但直接對 FsImage
進(jìn)行增量編輯效率不高。我們不會修改每個編輯的 FsImage
,而是在 Editlog
中保留編輯內(nèi)容。
在檢查點期間,Editlog
的更改將應(yīng)用于 FsImage
。可以以秒為單位的給定時間間隔(dfs.namenode.checkpoint.period)觸發(fā)檢查點,或者在累積給定數(shù)量的文件系統(tǒng)事務(wù)(dfs.namenode.checkpoint.txns)之后觸發(fā)檢查點。如果同時設(shè)置了這兩個屬性,則一旦滿足其中一個閾值就可觸發(fā)檢查點。
五、數(shù)據(jù)復(fù)制(Data Replication)
HDFS
旨在跨大型集群中的計算機(jī)可靠地存儲非常大的文件。它將每個文件存儲為一系列塊,除最后一個塊之外的文件中的所有塊都具有相同的大小,HDFS
使用的默認(rèn)塊大小為 128MB。復(fù)制文件的塊以實現(xiàn)容錯,且一般復(fù)制出的文件塊會存儲到不同的 DataNode
中。數(shù)據(jù)塊的大小以及復(fù)制因子都是可以由用戶設(shè)置。
HDFS中的文件是一次寫入的,并且在任何時候都只能有一個寫入器。
解釋:如圖所示,part-0
文件復(fù)制因子為r:2
,其拆分的數(shù)據(jù)塊號有{1,3}
,所以 1 號數(shù)據(jù)塊在第1,第3個 DataNode
上,3 號數(shù)據(jù)塊在第5,第6個DataNode
上;part-1
文件解釋同理。而這些信息都存儲在 NameNode
中。
HDFS 副本存放策略
剛剛只是簡單的介紹了圖里的信息,實際 HDFS
副本放置策略是一個值得研究的課題,因為這切實關(guān)系到 HDFS
的可依賴性與表現(xiàn),并且經(jīng)過優(yōu)化的副本放置策略也使得 HDFS
相比其他分布式文件系統(tǒng)具有優(yōu)勢。
在大部分的實際案例中,當(dāng)復(fù)制因子是 r = 3
時,HDFS
的放置策略是將一個復(fù)制品放置到寫入器操作的 DataNode
中,第二個復(fù)制品放置到另一個遠(yuǎn)程機(jī)架上的一個節(jié)點中,然后最后一個復(fù)制品則放置同一個遠(yuǎn)程機(jī)架的不同物理節(jié)點中。
這種放置策略可以有效的減少機(jī)架之中的通信以提高系統(tǒng)的表現(xiàn)。因為不同機(jī)架的物理節(jié)點的通信需要通過交換機(jī),而在大多數(shù)情況下,同一機(jī)架中的計算機(jī)之間的網(wǎng)絡(luò)帶寬大于不同機(jī)架中的計算機(jī)之間的網(wǎng)絡(luò)帶寬。
如果復(fù)制因子大于3,則隨機(jī)確定第4個及以后副本的放置,同時保持每個機(jī)架的副本數(shù)量低于上限。
上限數(shù)一般為(副本數(shù)-1)/ 機(jī)架 + 2
由于 NameNode
不允許 DataNode
具有同一塊的多個副本,因此,能創(chuàng)建的最大副本數(shù)是此時 DataNode
的總數(shù)。
當(dāng)有客戶端請求讀取時,HDFS
為了最小化全局帶寬消耗與讀取延遲,會優(yōu)先選擇離讀取客戶端最近的數(shù)據(jù)副本。
六、通信協(xié)議
所有 HDFS
通信協(xié)議都分層在 TCP/IP
協(xié)議之上。
七、數(shù)據(jù)復(fù)制流水線
當(dāng)客戶端將數(shù)據(jù)寫入復(fù)制因子為 r = 3
的 HDFS
文件時,NameNode
使用 replication target choosing algorithm
檢索 DataNode
列表。此列表包含將承載該塊副本的 DataNode
。
然后客戶端向第一個 DataNode
寫入,第一個 DataNode
開始分批接收數(shù)據(jù),將每個部分寫入其本地存儲,并將該部分傳輸?shù)搅斜碇械牡诙€ DataNode
。第二個 DataNode
又開始接收數(shù)據(jù)塊的每個部分,將該部分寫入其存儲,然后將該部分刷新到第三個 DataNode
。最后,第三個 DataNode
將數(shù)據(jù)寫入其本地存儲。
可見,DataNode
是從流水線中的前一個接收數(shù)據(jù),同時將數(shù)據(jù)轉(zhuǎn)發(fā)到流水線中的下一個,數(shù)據(jù)是從一個 DataNode
流水線到下一個 DataNode
。
八、可操作
應(yīng)用可以以多種方式操控 HDFS
上的文件,其中通過 FS Shell
可以像操控 Linux
文件系統(tǒng)一般,常用命令有:
Action | Command |
---|---|
創(chuàng)建 foodir 文件夾 | bin/hadoop fs -mkdir /foodir |
刪除文件夾 | bin/hadoop fs -rm -R /foodir |
查看文件內(nèi)容 | bin/hdfs dfs -cat /foodir/myfile.txt |
上傳文件 | bin/hdfs dfs -copyFromLocal ~/a.txt /foodir/ |
…… | …… |
會發(fā)現(xiàn)這里有兩種命令前綴,一個是
hadoop fs
,一個是hdfs dfs
區(qū)別是:
hadoop fs
可以用于其他文件系統(tǒng),不止是hdfs文件系統(tǒng)內(nèi),也就是說該命令的使用范圍更廣;而hdfs dfs
專門針對hdfs分布式文件系統(tǒng)。還有一個前綴為
hadoop dfs
,這個已經(jīng)過時,建議不要使用??。
九、空間回收
9.1 文件刪除和取消刪除
如果啟用了垃圾箱配置,則 FS Shell
刪除的文件不會立即從 HDFS
中刪除,而是 HDFS
將其移動到垃圾目錄(/user/username/.Trash)。
在垃圾箱中,被刪除文件的生命周期到期后,NameNode
將從 HDFS
命名空間中刪除該文件。刪除文件會導(dǎo)致釋放與文件關(guān)聯(lián)的塊。
注意:在用戶刪除文件的時間與
HDFS
中相應(yīng)增加的可用空間之間可能存在明顯的時間延遲。
如果啟用了垃圾箱配置,想直接徹底刪除,命令為:hadoop fs -rm -r -skipTrash a.txt
9.2 減少復(fù)制因子
當(dāng)文件的復(fù)制因子減少時,NameNode
選擇可以刪除的多余副本。下一個 Heartbeat
將此信息傳輸?shù)?DataNode
。然后,DataNode
刪除相應(yīng)的塊,并在群集中顯示相應(yīng)的可用空間。
參考
[1] Hadoop JavaDoc API
[2] HDFS 源碼: http://hadoop.apache.org/version_control.html
[3] HDFS 文檔:
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html