Yarn執行Mapreduce程式的工作原理
元件說明:
NodeManager
每個節點上裝有一個NM,主要的職責有:
(1)為應用程式啟動容器,同時確保申請的容器使用的資源不會超過節點上的總資源。
(2)為task構建容器環境,包括二進位制可執行檔案,jars等。
(3)為所在的節點提供了一個管理本地儲存資源的簡單服務,應用程式可以繼續使用本地儲存資源即使它沒有從RM那申請。比如:MapReduce可以使用該服務程式儲存map task的中間輸出結果。
排程器
排程器收集所有正在執行的應用程式的資源請求並構建一個全域性規劃進行資源分配。排程器會根據應用程式相關的約束(如合適的機器)和全域性約束(如佇列資源總量,使用者可提交作業總數等)分配資源。
排程器使用與容量排程類似的概念,採用容量保證作為基本的策略在多個應用程式間分配資源。
排程器的排程策略如下:
· 選擇系統中“服務最低”的佇列(如何定義服務最低?可以是資源利用量最低的佇列,即:已使用的資源與總共可用資源比值最小)
· 從該佇列中選擇優先順序最高的作業
· 儘量滿足該作業的資源請求
ASM
ASM負責管理系統中所有應用程式的AM,ASM負責啟動AM,監控AM的執行狀態,在AM失敗時對其進行重啟等。
為了完成該功能,ASM主要有以下幾個元件:
(1) SchedulerNegotiator:與排程器協商容器資源,並返回給AM
(2) AMContainerManager:告知NM,啟動或者停止某個AM的容器
(3) AMMonitor:檢視AM是否活著,並在必要的時候重啟AM
ApplicationMaster
每個應用程式均會有一個AM,主要職責有:
(1) 與排程器協商資源
(2) 與NM合作,在合適的容器中執行對應的task,並監控這些task執行
(3) 如果container出現故障,AM會重新向排程器申請資源
(4) 計算應用程式所需的資源量,並轉化成排程器可識別的格式(協議)
(5) AM出現故障後,ASM會重啟它,而由AM自己從之前儲存的應用程式執行狀態中恢復應用程式。
排程器API
Yarn排程器與AM之間僅有一個API:
Response allocate(List ask, List release);
AM使用一個ResourceRequest列表請求特定資源,並同時可要求釋放一些排程器已經分配的容器。
Response包含三方面內容:新分配的容器列表,自從上次AM與RM互動以來已經計算完成的容器的狀態(包含該容器中執行task的詳細資訊),當前叢集中剩餘資源量。 AM收集完成容器的資訊並對失敗的任務作出反應。資源剩餘量可用於AM調整接下來的資源請求,如MapReduce AM可使用該資訊以合理排程maps和reduces從而防止產生死鎖。
第 1 步:Client執行main()函式中run job(),開啟作業
通過submit或者waitForCompletion提交作業,waitForCompletion()方法通過每秒迴圈輪轉作業進度,如果發現與上次報告有改變,則將進度報告發送到控制檯。其實waitForComplection()方法中還是呼叫submit()方法。
第 2 步:client向RM傳送作業請求同時RM將作業id(在YARN中叫做應用程式ID)以及jar包存放路徑返回給Client。
客戶端向ResourceManager提交請求GetNewApplicationRequest,ResourceManager為其返回應答GetNewApplicationResponse,該資料結構中包含多種資訊,包括ApplicationId、可資源使用上限和下限等。
第 3 步:這時候作業客戶端檢查輸出說明、計算輸入分片(可以通過yarn.app.mapreduce.am.computer-splits-in-cluster在叢集上產生分片)。Client會把Jar路徑為字首作業id為字尾作為唯一存放路徑,並將作業資訊(jar、配置檔案、分片資訊)寫入到HDFS叢集中,預設情況下jar包寫10份,而其他資料只寫3份,當該程式執行完後刪除這些資料
第 4 步:客戶端Client將啟動ApplicationMaster所需的所有資訊(包括描述更為詳細的Jar存放地址)打包到資料結構ApplicationSubmissionContext中,然後呼叫submitApplication(ApplicationSubmissionContext)將ApplicationMaster提交到ResourceManager上。
第 5 步(5a-5b):資源管理器RM在收到submitApplication()訊息後,將其放入排程器(Scheduler),排程器為其分配一個容器Container,向NM傳送命令,然後NM在RM的管理下在container中啟動MRAPPMaster程序
ApplicationMaster首先需向ResourceManager傳送註冊請求RegisterApplicationMasterRequest,而ResourceManager將返回RegisterApplicationMasterResponse。
**第 6 步:**applicationmaster對作業進行初始化,建立過個薄記物件以跟蹤作業進度。MR根據HDFS中jar包資料量為NM分配任務.
**第 7 步:**applicationmaster接受來自HDFS在客戶端計算的輸入分片,對每一個分片建立一個map任務,任務物件,由mapreduce.job.reduces屬性設定reduce個數。
uber模式
當任務小的時候就會啟動一個JVM執行MapReduce作業,這在MapReduce1中是不允許的,這樣的作業在YARN中成為uber作業,通過設定mapreduce.job.ubertask.enable設定為false使用。
那什麼是小任務呢?
當小於10個mapper且只有1個reducer且輸入大小小於一個HDFS塊的任務。
但是這三個值可以重新設定:mapreduce.job.ubertask.maxmaps
第 8 步:如果作業不適合uber任務執行,applicationmaster就會為所有的map任務和reduce任務向資源管理器申請容器(Container,僅包含記憶體和cpu兩類資源)。
ApplicationMaster使用ResourceRequest類描述每個Container。一旦為任務構造了Container後,ApplicationMaster會向ResourceManager傳送一個AllocateRequest物件,以請求分配這些Container。ResourceManager會為ApplicationMaster返回一個AllocateResponse物件。
請求作業為任務指定記憶體需求,map任務和reduce任務的預設都會申請1024MB的記憶體,這個值可以通過mapreduce.map.memory.mb和mapreduce.reduce.memory.mb來設定。
這裡的記憶體分配策略和mapreduce1中不同,在MR1中tasktracker中有固定數量的槽,每個任務執行在一個槽(slot)中,槽有最大記憶體分配限制,這樣叢集是固定的,當任務使用較少記憶體時,無法充分使用槽的記憶體,造成其他任務不能夠獲取足夠記憶體因而導致作業失敗。
在YARN中,資源分為更細的粒度,所以避免了以上的問題。應用程式可以申請最小到最大記憶體限制的任意最小值的倍數的記憶體容量。預設值是1024~10240,可以通過yarn.scheduler.capacity.minimum-allocation-mb和yarn.scheduler.capacity.maximum-allocation.mb設定。任務可以通過設定mapreduce.map.memory.mb和mapreduce.reduce.memory.mb來請求1GB到10GB的任意1GB的整數倍的記憶體容量。
第 9 步(9a~9b):資源管理器為任務分配了容器,當ApplicationMaster(從ResourceManager端)收到新分配的Container列表後,會向對應的NodeManager傳送ContainerLaunchContext以啟動Container。NM會開啟內部YARNChild,由YarnChild的java應用程式執行。
第 10 步:執行任務之前,首先將資源本地化,包括作業配置、jar檔案和所有來自分散式快取的檔案。YARNChild根據命令到HDFS檢索作業資源。
**第 11 步:**YARNChild開啟MapTask 或者Reduce Task
ApplicationMaster會不斷重複步驟8~9,直到所有任務執行成功。