原文地址:pengtuo.tech/2018/09/10/…html
Hadoop
生態是一個龐大的、功能齊全的生態,可是圍繞的仍是名爲 Hadoop
的分佈式系統基礎架構,其核心組件由四個部分組成,分別是:Common
、HDFS
、MapReduce
以及 YARN
。node
Common
是 Hadoop
架構的通用組件;HDFS
是 Hadoop
的分佈式文件存儲系統;MapReduce
是Hadoop
提供的一種編程模型,可用於大規模數據集的並行運算;YARN
是 Hadoop
架構升級後,目前普遍使用的資源管理器。小目標是爲每個核心組件寫一篇全解的博文,本篇先來好好了解下 HDFS
。apache
HDFS(The Hadoop Distributed File System),是被設計成適合運行在通用硬件(commodity hardware
)上的 Hadoop
的分佈式文件系統。它與其餘的分佈式系統有很是顯著的不一樣,首先 HDFS
具備高容錯性,而且它能夠被部署到廉價的硬件上。此外,HDFS
提供對應用程序數據的高吞吐量訪問,適用於具備大型數據集的應用程序。編程
目前,HDFS
做爲 Apache Hadoop
的核心項目,URL爲:hadoop.apache.org/api
一個 HDFS
實例有可能包含數百臺或數千臺服務器,每個臺機器都存儲文件系統數據的一部分,這種狀況下硬件故障是常態。而 HDFS
可檢測故障並從中快速自動恢復。服務器
HDFS
設計用於批處理而不是用戶的交互式使用,其重點是數據訪問的高吞吐量而並不追求數據訪問的低延遲。網絡
HDFS
的核心目標就是爲處理具備大數據量的應用,在其上運行的應用的文件大小通常都爲 TB
級別。HDFS
可提供高聚合數據帶寬而且要擴展到集羣中的數百個節點上,並對於單個應用可支持上千萬個文件。架構
HDFS
應用程序是一個"一次寫入屢次讀取"的文件訪問模型。這種模型能夠簡化數據的一致性問題而且可以實現高吞吐數據訪問。官方文檔表示有計劃支持追加寫入文件的功能。分佈式
「Moving Computation is Cheaper than Moving Data」,當一個計算程序與數據同在一個物理節點上時,運算最高效,特別是當數據量特別大時,移動計算遠優於移動數據集。移動計算能夠最大限度地減小網絡擁塞並提升系統的總體吞吐量。HDFS
設計的是將計算遷移到更靠近數據所在的位置,而不是將數據移動到運行應用程序的位置。HDFS
爲應用程序提供了接口,使其自身更靠近數據。oop
HDFS
的設計便於從一個平臺移植到另外一個平臺。 這有助於普遍採用 HDFS
做爲大量應用程序的首選大數據處理平臺。
NameNode
與 DataNode
是 HDFS
系統的重要知識點。HDFS
是 master/slave
體系結構。一個 HDFS
集羣是由單個 NameNode
和衆多 DataNode
組成,文件會被分紅一個或多個塊,這些塊存儲在一組 DataNode
中。
由於 HDFS
是用 Java 語言搭建的,因此只要是支持 Java 語言的機器均可以運行 NameNode
和 DataNode
。而且由於 Java 的高可移植性,HDFS
也具備很是普遍的應用範圍。一種典型的 HDFS
部署模式是指定一個物理主機運行 NameNode
,而後其他的機器運行 DataNode
,在實際部署狀況中,通常都是一臺主機部署一個 DataNode
。
羣集中存在單個 NameNode
極大地簡化了系統的體系結構。 NameNode
是全部 HDFS
元數據的決定者和存儲庫。系統的這種設計使用戶數據永遠不會流經 NameNode
,可理解 NameNode
爲整個系統的中樞。
架構以下圖:
首先圖中的 rack
翻譯爲「機架」,能夠理解爲兩個處於不一樣地方的機羣,每一個機羣內部有本身的鏈接方式。其次在 DataNode
中存儲的不是當個文件,而是文件塊(Block),在 HDFS
中,每一個大文件會拆分紅多個 Block
,而後將這些 Block
散佈存儲在不一樣的 DataNode
中,而且每一個 Block
會有多個複製,也會存儲到其餘的 DataNode
中。
能夠看出上圖分別解釋了「讀」和「寫」兩種操做:
HDFS
寫入文件時,圖中將文件拆分的 Block
寫入到了兩個機架的 DataNode
中,通常狀況下就是兩個機架的兩個物理主機中,能夠看出文件數據沒有通過 NameNode
。數據寫入的過程見(「7、數據複製流水線」)HDFS
讀取文件時,會將操做命令傳向 NameNode
,而後 NameNode
轉爲對應的數據塊的操做,指揮相應的 DataNode
將所需數據返回給客戶端。還有一個節點圖中沒有顯示,叫做
Secondary Namenode
,是輔助後臺程序,主要負責與NameNode
進行通訊,按期保存HDFS
元數據的快照及備份其餘NameNode
中的內容,平常Standby
,當NameNode
故障時頂替NameNode
使用。
NameNode
是管理文件系統命名空間的主服務器,用於管理客戶端對文件的訪問,執行文件系統命名空間操做,如打開,關閉和重命名文件和目錄。它還肯定了Block
到 DataNode
的映射。
NameNode
作着有關塊複製的全部決定,它按期從羣集中的每一個 DataNode
接收 Heartbeat
和 Blockreport
。收到 Heartbeat
意味着 DataNode
正常運行,Blockreport
包含 DataNode
上全部塊的列表。
DataNode
一般是羣集中每一個節點一個,用於存儲數據,負責提供來自文件系統客戶端的讀寫請求。而且還會根據 NameNode
的指令執行塊建立,刪除和複製。
HDFS
支持傳統的分層文件組織,文件系統命名空間層次結構與大多數其餘現有文件系統相似,一個用戶或者應用能夠建立文件夾而且在這個文件夾裏存儲文件。可是 HDFS
不支持 Linux 裏的硬連接和軟鏈接。NameNode
維護着文件系統的命名空間,其記錄對文件系統命名空間或其屬性的任何更改,NameNode
還會存儲複製因子。
數據塊的副本數稱爲該數據塊的複製因子
文件系統的元數據(MetaData
)也存儲在 NameNode
中,NameNode
使用名爲 EditLog
的事務日誌來持久記錄文件系統元數據發生的每一個更改。例如,在 HDFS
中建立新文件會致使 NameNode
將記錄插入 EditLog
,以指示此狀況。NameNode
使用其本地主機OS文件系統中的文件來存儲 EditLog
。
而整個文件系統命名空間(包括塊到文件和文件系統屬性的映射)存儲在名爲 FsImage
的文件中。 FsImage
也做爲文件存儲在 NameNode
的本地文件系統中。
NameNode
在整個內存中保存整個文件系統命名空間和文件的數據塊映射。當 NameNode
啓動,或者檢查點由可配置的閾值觸發時,它從磁盤讀取 FsImage
和 EditLog
,並先將 FsImage
中的文件系統元數據信息加載到內存,而後把 EditLog
中的全部事務應用到內存中的 FsImage
,最後將此新版本同步到磁盤上的 FsImage
。而後它能夠截斷舊的 EditLog
,由於它的事務已應用於持久性 FsImage
。此過程稱爲檢查點。
檢查點的目的是經過獲取文件系統元數據的快照並將其保存到 FsImage
來確保 HDFS
具備文件系統元數據的一致視圖。儘管直接從內存中讀取 FsImage
很高效,但直接對 FsImage
進行增量編輯效率不高。咱們不會修改每一個編輯的 FsImage
,而是在 Editlog
中保留編輯內容。
在檢查點期間,Editlog
的更改將應用於 FsImage
。能夠以秒爲單位的給定時間間隔(dfs.namenode.checkpoint.period)觸發檢查點,或者在累積給定數量的文件系統事務(dfs.namenode.checkpoint.txns)以後觸發檢查點。若是同時設置了這兩個屬性,則一旦知足其中一個閾值就可觸發檢查點。
HDFS
旨在跨大型集羣中的計算機可靠地存儲很是大的文件。它將每一個文件存儲爲一系列塊,除最後一個塊以外的文件中的全部塊都具備相同的大小,HDFS
使用的默認塊大小爲 128MB。複製文件的塊以實現容錯,且通常複製出的文件塊會存儲到不一樣的 DataNode
中。數據塊的大小以及複製因子都是能夠由用戶設置。
HDFS中的文件是一次寫入的,而且在任什麼時候候都只能有一個寫入器。
解釋:如圖所示,part-0
文件複製因子爲r:2
,其拆分的數據塊號有{1,3}
,因此 1 號數據塊在第1,第3個 DataNode
上,3 號數據塊在第5,第6個DataNode
上;part-1
文件解釋同理。而這些信息都存儲在 NameNode
中。
剛剛只是簡單的介紹了圖裏的信息,實際 HDFS
副本放置策略是一個值得研究的課題,由於這切實關係到 HDFS
的可依賴性與表現,而且通過優化的副本放置策略也使得 HDFS
相比其餘分佈式文件系統具備優點。
在大部分的實際案例中,當複製因子是 r = 3
時,HDFS
的放置策略是將一個複製品放置到寫入器操做的 DataNode
中,第二個複製品放置到另外一個遠程機架上的一個節點中,而後最後一個複製品則放置同一個遠程機架的不一樣物理節點中。
這種放置策略能夠有效的減小機架之中的通訊以提升系統的表現。由於不一樣機架的物理節點的通訊須要經過交換機,而在大多數狀況下,同一機架中的計算機之間的網絡帶寬大於不一樣機架中的計算機之間的網絡帶寬。
若是複製因子大於3,則隨機肯定第4個及之後副本的放置,同時保持每一個機架的副本數量低於上限。
上限數通常爲(副本數-1)/ 機架 + 2
因爲 NameNode
不容許 DataNode
具備同一塊的多個副本,所以,能建立的最大副本數是此時 DataNode
的總數。
當有客戶端請求讀取時,HDFS
爲了最小化全局帶寬消耗與讀取延遲,會優先選擇離讀取客戶端最近的數據副本。
全部 HDFS
通訊協議都分層在 TCP/IP
協議之上。
當客戶端將數據寫入複製因子爲 r = 3
的 HDFS
文件時,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
,這個已通過時,建議不要使用🙅。
若是啓用了垃圾箱配置,則 FS Shell
刪除的文件不會當即從 HDFS
中刪除,而是 HDFS
將其移動到垃圾目錄(/user/username/.Trash)。
在垃圾箱中,被刪除文件的生命週期到期後,NameNode
將從 HDFS
命名空間中刪除該文件。刪除文件會致使釋放與文件關聯的塊。
注意:在用戶刪除文件的時間與
HDFS
中相應增長的可用空間之間可能存在明顯的時間延遲。
若是啓用了垃圾箱配置,想直接完全刪除,命令爲:hadoop fs -rm -r -skipTrash a.txt
當文件的複製因子減小時,NameNode
選擇能夠刪除的多餘副本。下一個 Heartbeat
將此信息傳輸到 DataNode
。而後,DataNode
刪除相應的塊,並在羣集中顯示相應的可用空間。
[1] Hadoop JavaDoc API
[2] HDFS 源碼: hadoop.apache.org/version_con…
[3] HDFS 文檔: hadoop.apache.org/docs/stable…