Hadoop-MapReduce2.x-yarn框架
1.mapreduce1.0的不足
- JobTracker 是 Map-reduce 的集中處理點,存在單點故障。
- JobTracker 完成了太多的任務,造成了過多的資源消耗,當 map-reduce job 非常多的時候,會造成很大的內存開銷,潛在來說,也增加了 JobTracker fail 的風險,這也是業界普遍總結出老 Hadoop 的 Map-Reduce 只能支持 4000 節點主機的上限。
- 在 TaskTracker 端,以 map/reduce task 的數目作為資源的表示過于簡單,沒有考慮到 cpu/內存的占用情況,如果兩個大內存消耗的 task 被調度到了一塊,很容易出現 OOM。
- 在 TaskTracker 端,把資源強制劃分為 map task slot 和 reduce task slot, 如果當系統中只有 map task 或者只有 reduce task 的時候,會造成資源的浪費,也就是前面提過的集群資源利用的問題。源代碼層面分析的時候,會發現代碼非常的難讀,常常因為一個 class 做了太多的事情,代碼量達 3000 多行造成 class 的任務不清晰,增加 bug 修復和版本維護的難度。
- 從操作的角度來看,現在的 Hadoop MapReduce 框架在有任何重要的或者不重要的變化 ( 例如 bug 修復,性能提升和特性化 ) 時,都會強制進行系統級別的升級更新。更糟的是,它不管用戶的喜好,強制讓分布式集群系統的每一個用戶端同時更新。這些更新會讓用戶為了驗證他們之前的應用程序是不是適用新的 Hadoop 版本而浪費大量時間。
2.Hadoop2.x中新方案YARN+MapReduce
首先的不要被YARN給迷惑住了,它只是負責資源調度管理,而MapReduce才是負責運算的家伙,所以YARN != MapReduce2.這是大師說的:
YARN并不是下一代MapReduce(MRv2),下一代MapReduce與第一代MapReduce(MRv1)在編程接口、數據處理引擎(MapTask和ReduceTask)是完全一樣的, 可認為MRv2重用了MRv1的這些模塊,不同的是資源管理和作業管理系統,MRv1中資源管理和作業管理均是由JobTracker實現的,集兩個功能于一身,而在MRv2中,將這兩部分分開了, 其中,作業管理由ApplicationMaster實現,而資源管理由新增系統YARN完成,由于YARN具有通用性,因此YARN也可以作為其他計算框架的資源管理系統,不僅限于MapReduce,也是其他計算框架(Spark).
? ? 看上圖我們可以知道Hadoop1中mapreduce可以說是啥事都干,而Hadoop2中的MapReduce的話則是專門處理數據分析.而YARN的話則做為資源管理器存在.
在Hadoop2中將JobTracker兩個主要的功能分離成單獨的組件,這兩個功能是資源管理和任務調度/監控。新的資源管理器全局管理所有應用程序計算資源的分配,每一個應用的 ApplicationMaster 負責相應的調度和協調。一個應用程序無非是一個單獨的傳統的 MapReduce 任務或者是一個 DAG( 有向無環圖 ) 任務。ResourceManager 和每一臺機器的節點管理服務器能夠管理用戶在那臺機器上的進程并能對計算進行組織。
1.事實上,每一個應用的ApplicationMaster是一個詳細的框架庫,它結合從ResourceManager獲得的資源和 NodeManagr 協同工作來運行和監控任務。
2.在上圖中ResourceManager支持分層級的應用隊列,這些隊列享有集群一定比例的資源。從某種意義上講它就是一個純粹的調度器,它在執行過程中不對應用進行監控和狀態跟蹤。同樣,它也不能重啟因應用失敗或者硬件錯誤而運行失敗的任務。
ResourceManager 是基于應用程序對資源的需求進行調度的 ; 每一個應用程序需要不同類型的資源因此就需要不同的容器。資源包括:內存,CPU,磁盤,網絡等等。可以看出,這同現 Mapreduce 固定類型的資源使用模型有顯著區別,它給集群的使用帶來負面的影響。資源管理器提供一個調度策略的插件,它負責將集群資源分配給多個隊列和應用程序。調度插件可以基于現有的能力調度和公平調度模型。
3.在上圖中 NodeManager 是每一臺機器框架的代理,是執行應用程序的容器,監控應用程序的資源使用情況 (CPU,內存,硬盤,網絡 ) 并且向調度器匯報。
4.在上圖中,每一個應用的 ApplicationMaster的職責有:向調度器索要適當的資源容器,運行任務,跟蹤應用程序的狀態和監控它們的進程,處理任務的失敗原因。
1.客戶端的mapreduce程序通過hadoop shell提交到hadoop的集群中.
2.程序會通過RPC通信將打成jar包的程序的有關信息傳遞給Hadoop集群中RM(ResourceManager),可稱為領取JOBID的過程
3.RM更加提交上來的信息給任務分配一個唯一的ID,同時會將run.jar的在HDFS上的存儲路徑發送給客戶端.
4.客戶端得到那個存儲路徑之后,會相應的拼接出最終的存放路徑目錄,然后將run.jar分多份存儲在HDFS目錄中,默認情況下備份數量為10份.可配置.
5.客戶端提交一些配置信息,例如:最終存儲路徑,JOB ID等.
6.RM會將這些配置信息放入一個隊列當中,所謂的調度器.至于調度的算法,則不必深究.
7.NM(NodeManager)和RM是通過心跳機制保持著通信的,NM會定期的向RM去領取任務.
8.RM會在任意的一臺或多臺的NM中,啟動任務監控的進程Application Master.用來監控其他NM中YARN CHild的執行的情況
9.NM在領取到任務之后,得到信息,會去HDFS的下載run.jar.然后在本地的機器上啟動YARN Child進程來執行map或者reduce函數.map函數的處理之后的中間結果數據會放在本地文件系統中的.
10.在結束程序之后,將結果數據寫會HDFS中.整個流程大概就是這樣子的.
3.執行過程
作業提交
Job實例調用submit()方法提交一個作業,這個方法會創建一個JobSubmitter實例(圖中第1步)。提交完作業后,waitForCompletion(如果代碼中調用了的話)方法會每隔一秒查看作業的狀態并且將變化(如果有的話)打印到終端。
在JobSubmitter中會做如下事情:
向Yarn RM中請求一個新的應用ID,分配給這個MR作業(第2步)。 檢查作業的輸出需求。例如,如果輸出目錄已經存在,則不提交作業并且拋出一個異常。 計算作業的輸入切片(準確說是切片信息)。如果切片不能被計算出來(例如輸入目錄不存在),同樣作業不會被提交并且發出一個異常。 拷貝各種作業資源(例如作業的jar包,配置文件,切片信息等)到分布式文件系統下的一個被命名為job ID的目錄下(第3步)。 調用submitApplicatiion方法提交作業到Yarn RM(第4步)。
作業初始化
當Yarn RM收到了submitApplicatiion方法中的請求。它將這個請求交給Yarn調度器。調度器會分配一個容器,然后Yarn RM在這個容器中啟動一個AM(在NM管理下)(5a和5b)。
AM是一個java應用,它的主類叫做MRAppMaster。這個類會創建一些記錄對象,用來獲取來自任務的報告(第6步)。然后會從分布式文件系統中獲取切片信息(第7步)。為每一個分片創建一個map任務,而reduce任務的個數由mapreduce.job.reduces屬性或者setNumReduceTasks方法指定。同樣任務的ID也在這個時候被分配。
AM也需要決定如何運行這些任務。如果作業太小,AM則把所有的任務跑在一個JVM中。這種作業被稱為uber任務。
任務分配
如果作業不是uber任務,AM則會從RM那里為每一個map和reduce任務請求一個容器(第8步)。當然為map請求容器的優先級要高于reduce。事實上,reduce任務的請求直到至少5%的map任務完成才會被提出。
還需要注意到, map任務會盡量遵守locality約束,而reduce任務則可以運行在集群的任意地方。
任務執行
一旦RM給某個任務分配了某個特定節點上的容器,AM通過NM啟動這個容器(9a和9b)。這個任務是一個Java應用并且主類叫做YarnChild。在運行這個任務之前,它會先從分布式文件系統中獲取各種資源(第10步)。最后,它運行這個任務(第11步)。
狀態更新
當任務運行時,它記錄了自己的進度。對于map任務,是自己處理的分片的比例。對于reduce任務,稍微復雜一點,需要把整個過程分為三個部分,即shuffle和sort的三個階段:copy, sort 和reduce,然后再估算。
每個任務,會每三秒通過一個臍帶(umbilical)接口向AM報告自己的狀態,而client則每一秒從AM那里收到最新的進度。
作業完成
當AM收到最后一個任務完成的消息時,它會把作業的狀態變為“成功“。Job實例則獲得這個狀態后,告訴用戶并且它的waitForCompletion方法會返回值,同時各種統計信息會被打印出來。
稍微提一點的是,通過配置mapreduce.job.end-notification.url property參數,AM也會發送HTTP通知。
最后AM和任務的容器會清理它們的狀態。以及一些其他的收尾工作也在這時候被完成。