Hadoop 2.0工作原理學習

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的一個塊的大小(默認爲64M,可設置)爲一個分片。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函數。
 
原文:https://blog.csdn.net/carl810224/article/details/51910975 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章