1. 程式人生 > >HDFS2.X架構及工作原理

HDFS2.X架構及工作原理

1 HDFS簡介 1.1 Hadoop 2.0介紹 Hadoop是Apache的一個分散式系統基礎架構,可以為海量資料提供儲存和計算。Hadoop 2.0即第二代Hadoop系統,其框架最核心的設計是HDFS、MapReduce和YARN。其中,HDFS為海量資料提供儲存,MapReduce用於分散式計算,YARN用於進行資源管理。

Hadoop 1.0和Hadoop 2.0的結構對比:

 

Hadoop 2.0的主要改進有:

1、通過YARN實現資源的排程與管理,從而使Hadoop 2.0可以執行更多種類的計算框架,如Spark等。

2、實現了NameNode的HA方案,即同時有2個NameNode(一個Active另一個Standby),如果ActiveNameNode掛掉的話,另一個NameNode會轉入Active狀態提供服務,保證了整個叢集的高可用。

3、實現了HDFS federation,由於元資料放在NameNode的記憶體當中,記憶體限制了整個叢集的規模,通過HDFS federation使多個NameNode組成一個聯邦共同管理DataNode,這樣就可以擴大叢集規模。

4、Hadoop RPC序列化擴充套件性好,通過將資料型別模組從RPC中獨立出來,成為一個獨立的可插拔模組。

1.2 HDFS概述 HDFS是一個分散式檔案系統,具有高容錯的特點。它可以部署在廉價的通用硬體上,提供高吞吐率的資料訪問,適合需要處理海量資料集的應用程式。

主要特點:

1、支援超大檔案:支援TB級的資料檔案。

2、檢測和快速應對硬體故障:HDFS的檢測和冗餘機制很好克服了大量通用硬體平臺上的硬體故障問題。

3、高吞吐量:批量處理資料。

4、簡化一致性模型:一次寫入多次讀取的檔案處理模型有利於提高吞吐量。

HDFS不適合的場景:低延遲資料訪問;大量的小檔案;多使用者寫入檔案、修改檔案。

HDFS的構成:NameNode儲存著HDFS的名字空間,對於任何對檔案系統元資料產生修改的操作;DataNode將HDFS資料以檔案的形式儲存在本地檔案系統中,它並不知道有關HDFS檔案的資訊。

資料塊:資料塊是HDFS的檔案儲存處理單元,在Hadoop 2.0中預設大小為128MB,可根據業務情況進行配置。資料塊的存在,使得HDFS可以儲存比儲存節點單一磁碟大的檔案,而且簡化了儲存管理,方便容錯,有利於資料複製。

1.3 HDFS讀寫流程 讀檔案的流程:1、客戶端client使用open函式開啟檔案;2、DistributedFileSystem用RPC呼叫元資料節點,得到檔案的資料塊資訊;3、對於每一個數據塊,元資料節點返回儲存資料塊的資料節點的地址;4、DistributedFileSystem返回FSDataInputStream給客戶端,用來讀取資料;5、客戶端呼叫FSDataInputStream的read函式開始讀取資料;6、FSDataInputStream連線儲存此檔案第一個資料塊的最近的資料節點;7、Data從資料節點讀到客戶端;8、當此資料塊讀取完畢時,FSDataInputStream關閉和此資料節點的連線,然後連線此檔案下一個資料塊的最近的資料節點;9、當客戶端讀取資料完畢時,呼叫FSDataInputStream的close函式;10、在讀取資料的過程中,如果客戶端在與資料節點通訊出現錯誤,則嘗試連線包含此資料塊的下一個資料節點。失敗的資料節點將被記錄,以後不再連線。HDFS的讀檔案流程如下圖所示:

 

寫檔案的流程:1、客戶端client呼叫create函式建立檔案;2、DistributedFileSystem用RPC呼叫元資料節點,在檔案系統的名稱空間中建立一個新的檔案;3、元資料節點首先確定檔案是否存在,並且客戶端是否有建立檔案的許可權,然後建立新檔案;4、DistributedFileSystem返回FSDataOutputStream給客戶端用於寫資料;5、客戶端開始寫入資料,FSDataOutputStream將資料分成塊,寫入data queue;6、Data queue由DataStreamer讀取,並通知元資料節點分配資料節點,用來儲存資料塊(每塊預設複製3塊),分配的資料節點放在一個pipeline裡;7、DataStreamer將資料塊寫入pipeline中的第一個資料節點,第一個資料節點將資料塊傳送給第二個資料節點,第二個資料節點將資料傳送給第三個資料節點;8、FSDataOutputStream為發出去的資料塊儲存了ack queue,等待pipeline中的資料節點告知資料已經寫入成功;9、如果資料節點在寫入的過程中失敗,則進行以下幾個操作:一是關閉pipeline並將ack queue中的資料塊放入data queue的開始;二是當前資料塊在已寫入的資料節點中被元資料節點賦予新的標示,錯誤節點重啟後察覺其資料塊過時而被刪除;三是失敗的資料節點從pipeline中移除,另外的資料塊則寫入pipeline中的另外兩個資料節點;四是元資料節點被通知此資料塊的複製塊數不足,從而再建立第三份備份;10、當客戶端結束寫入資料,則呼叫close函式將所有的資料塊寫入pipeline中的資料節點,並等待ack queue返回成功,最後通知元資料節點寫入完畢。HDFS的寫檔案流程如下圖所示:

 

2 YARN原理介紹 2.1 YARN產生背景 Hadoop 1.0的弊端包括:

1、擴充套件性差:JobTracker同時兼備了資源管理和作業控制兩個功能,這是整個系統的最大瓶頸,它嚴重製約了整個叢集的擴充套件性。

2、可靠性差:JobTracker存在單點故障,JobTracker出現問題將導致整個叢集不可用。

3、資源利用率低:資源無法在多個任務間共享或合理分配,導致無法有效利用各種資源。

4、無法支援多種計算框架:Hadoop 1.0只支援MapReduce這種離線批處理計算模式,而無法支援記憶體計算、流式計算、迭代式計算等。

正是由於Hadoop 1.0存在以上這些弊端,所以Hadoop 2.0推出了資源管理器YARN,有效解決了上述問題。

2.2 YARN基本架構 YARN是Hadoop 2.0的資源管理器。它是一個通用的資源管理系統,可為上層應用提供統一的資源管理和排程,它的引入為叢集在利用率、資源統一管理和資料共享等方面帶來了巨大好處。

YARN的基本設計思想是將Hadoop 1.0中的JobTracker拆分成了兩個獨立的服務:一個全域性的資源管理器ResourceManager和每個應用程式特有的ApplicationMaster。其中ResourceManager負責整個系統的資源管理和分配,而ApplicationMaster負責單個應用程式的管理,其基本架構如下圖所示:

 

YARN總體上仍然是Master/Slave結構。在整個資源管理框架中,ResourceManager為Master,NodeManager為Slave,並通過HA方案實現了ResourceManager的高可用。ResourceManager負責對各個NodeManager上的資源進行統一管理和排程。當用戶提交一個應用程式時,需要提供一個用以跟蹤和管理這個程式的ApplicationMaster,它負責向ResourceManager申請資源,並要求NodeManger啟動可以佔用一定資源的任務。由於不同的ApplicationMaster被分佈到不同的節點上,因此它們之間不會相互影響。

ResourceManager:它是一個全域性的資源管理器,負責整個系統的資源管理和分配,主要由排程器和應用程式管理器兩個元件構成。

排程器:根據容量、佇列等限制條件,將系統中的資源分配給各個正在執行的應用程式。排程器僅根據應用程式的資源需求進行資源分配,而資源分配單位用一個抽象概念“資源容器”(簡稱Container)表示,Container是一個動態資源分配單位,它將記憶體、CPU、磁碟、網路等資源封裝在一起,從而限定每個任務使用的資源量。

應用程式管理器:負責管理整個系統中所有的應用程式,包括應用程式提交、與排程器協商資源以啟動ApplicationMaster、監控ApplicationMaster執行狀態並在失敗時重新啟動它等。

ApplicationMaster:使用者提交的每個應用程式均包含1個ApplicationMaster,主要功能包括與ResourceManager排程器協商以獲取資源、將得到的任務進一步分配給內部的任務、與NodeManager通訊以啟動/停止任務、監控所有任務執行狀態並在任務執行失敗時重新為任務申請資源以重啟任務等。

NodeManager:它是每個節點上的資源和工作管理員,它不僅定時向ResourceManager彙報本節點上的資源使用情況和各個Container的執行狀態,還接收並處理來自ApplicationMaster的Container啟動/停止等各種請求。

Container:它是YARN中的資源抽象,它封裝了某個節點上的多維度資源,如記憶體、CPU、磁碟、網路等,當ApplicationMaster向ResourceManager申請資源時,返回的資源便是用Container表示的。YARN會為每個任務分配一個Container,且該任務只能使用該Container中描述的資源。

2.3 YARN工作流程 YARN的工作流程如下圖所示:

 

步驟1:使用者向YARN中提交應用程式,其中包括使用者程式、ApplicationMaster程式、ApplicationMaster啟動命令等。

步驟2:ResourceManager為應用程式分配第一個Container,並與對應的NodeManager通訊,要求它在這個Container中啟動應用程式的ApplicationMaster。

步驟3:ApplicationMaster首先向ResourceManager註冊,這樣使用者可以直接通過ResourceManager檢視應用程式的執行狀態,然後ApplicationMaster為各個任務申請資源,並監控它們的執行狀態,直到執行結束,即重複步驟4-7。

步驟4:ApplicationMaster採用輪詢的方式通過RPC協議向ResourceManager申請和領取資源。

步驟5:一旦ApplicationMaster成功申請到資源,便開始與對應的NodeManager通訊,要求它啟動任務。

步驟6:NodeManager為任務設定好執行環境(包括環境變數、JAR包、二進位制程式等)後,將任務啟動命令寫到一個指令碼中,並通過執行該指令碼啟動任務。

步驟7:各個任務通過某個RPC協議向ApplicationMaster彙報自己的狀態和進度,使ApplicationMaster能夠隨時掌握各個任務的執行狀態,從而可以在任務失敗時重新啟動任務。在應用程式執行過程中,使用者可隨時通過RPC向ApplicationMaster查詢應用程式的當前執行狀態。

步驟8:應用程式執行完成後,ApplicationMaster通過RPC協議向ResourceManager登出並關閉自己。

3 MapReduce原理介紹

3.1 MapReduce介紹

MapReduce是由Google公司研究提出的一種面向大規模資料處理的平行計算模型和方法,是Hadoop面向大資料並行處理的計算模型、框架和平臺。

MapReduce執行流包括input、map、shuffle、reduce和output共5個過程,如下圖所示:

 

3.2MapReduce2執行原理 YARN框架下的Mapreduce工作流程如下圖所示:

 

步驟1:客戶端向叢集提交作業。

步驟2:Job從ResourceManager獲取新的作業應用程式ID。

步驟3:客戶端檢查作業的輸出情況,計算輸入分片,並將作業jar包、配置、分片資訊等作業資源複製到HDFS。

步驟4:Job向ResourceManager提交作業。

步驟5:ResourceManager接收到作業後,將作業請求傳遞給排程器,排程器根據作業資訊為ResourceManager分配一個container,然後ResourceManager在NodeManager的管理下,在container中啟動一個ApplicationMaster程序。

步驟6:ApplicationMaster對作業進行初始化,並保持對作業的跟蹤,判斷作業是否完成。

步驟7:ApplicationMaster根據儲存在HDFS中的分片資訊確定Map和Reduce的數量。

步驟8:ApplicationMaster為本次作業的Map和Reduce以輪詢的方式向ResourceManager申請container。

步驟9:ApplicationMaster獲取到container後,與NodeManager進行通訊啟動container。

步驟10:container從HDFS中獲取作業的jar包、配置和分散式快取檔案等,將任務需要的資源本地化。

步驟11:container啟動Map或Reduce任務。

3.3 shuffle及排序 Mapreduce的map端輸出作為輸入傳遞給reduce端,並按鍵排序的過程稱為shuffle。shuffle的字面含義是洗牌,即將map產生的資料通過分割槽、排序等過程分配給了不同的reduce任務。Mapreduce的資料處理流程如下圖所示:

 

Map階段:

1、每個輸入分片會讓一個map任務來處理,預設情況下,以HDFS的一個塊的大小(預設為128M,可設定)為一個分片。map輸出的結果會暫時放在一個環形記憶體緩衝區中(該緩衝區的大小預設為100M,由io.sort.mb屬性控制)。當該緩衝區快要溢位時(預設為緩衝區大小的80%,由io.sort.spill.percent屬性控制),會在本地檔案系統中建立一個溢位檔案,將該緩衝區中的資料寫入這個檔案。

2、在寫入磁碟之前,執行緒首先根據reduce任務的數目將資料劃分為相同數目的分割槽,也就是一個reduce任務對應一個分割槽的資料。這樣做是為了避免有些reduce任務分配到大量資料,而有些reduce任務卻分到很少資料,甚至沒有分到資料的尷尬局面。然後對每個分割槽中的資料進行排序,如果此時設定了Combiner,將排序後的結果進行combine操作,這樣做可以有效減少磁碟IO和網路IO。

3、當map任務輸出最後一個記錄時,可能會有很多的溢位檔案,這時需要將這些檔案合併。合併的過程中會不斷地進行排序和combine操作,這樣做是為了儘量減少每次寫入磁碟的資料量和儘量減少下一複製階段網路傳輸的資料量。最後合併成了一個已分割槽且已排序的檔案。為了減少網路傳輸的資料量,這裡可以將資料壓縮,只要將mapred.compress.map.out設定為true就可以了。

4、將分割槽中的資料拷貝給相對應的reduce任務。那麼分割槽中的資料如何知道它對應的reduce是哪個呢? ApplicationMaster儲存了整個作業的巨集觀資訊,只要reduce任務向ApplicationMaster獲取對應的map輸出位置就可以了。

Reduce階段:

1、Reduce會接收到不同map任務傳來的資料,並且每個map傳來的資料都是有序的。如果reduce接受的資料量相當小,則直接儲存在記憶體中,如果資料量超過了該緩衝區大小的一定比例,則對資料合併後溢寫到磁碟中。

2、隨著溢寫檔案的增多,後臺執行緒會將它們合併成一個更大的有序檔案,這樣做是為了給後面的合併節省時間。其實不管在map端還是reduce端,MapReduce都是反覆地執行排序、合併操作,所以說排序是hadoop的靈魂。

3、在合併的過程中會產生許多的中間檔案(寫入磁碟了),但MapReduce會讓寫入磁碟的資料儘可能地少,並且最後一次合併的結果並沒有寫入磁碟,而是直接輸入到reduce函式。