在YARN中,資源調度器(ResourceScheduler)是一個很是核心的部件,它負責將各個節點上的資源封裝成container,並按照必定的約束條件(按隊列分配,每一個隊列有必定的資源分配上限等)分配給各個application。node
(注意:本文分析基於hadoop-2.0.3-alpha)算法
YARN的資源管理器其實是一個事件處理器,它須要處理來自外部的6種SchedulerEvent類型的事件,並根據事件的具體含義進行相應的處理。這6種事件含義以下:apache
(1) NODE_REMOVED數據結構
事件NODE_REMOVED表示集羣中被移除一個計算節點(多是節點故障或者管理員主動移除),資源調度器收到該事件時須要從可分配資源總量中移除相應的資源量。app
(2) NODE_ADDED異步
事件NODE_ADDED表示集羣中增長了一個計算節點,資源調度器收到該事件時須要將新增的資源量添加到可分配資源總量中。函數
(3)APPLICATION_ADDEDoop
事件APPLICATION_ADDED 表示ResourceManager收到一個新的Application。一般而言,資源管理器須要爲每一個application維護一個獨立的數據結構,以便於統一管理和資源分配。資源管理器需將該Application添加到相應的數據結構中。spa
(4)APPLICATION_REMOVED線程
事件APPLICATION_REMOVED表示一個Application運行結束(可能成功或者失敗),資源管理器需將該Application從相應的數據結構中清除。
(5) CONTAINER_EXPIRED
當資源調度器將一個container分配給某個ApplicationMaster後,若是該ApplicationMaster在必定時間間隔內沒有使用該container,則資源調度器會對該container進行再分配。
(6)NODE_UPDATE
NodeManager經過心跳機制向ResourceManager彙報各個container運行狀況,會觸發一個NODE_UDDATE事件,因爲此時可能有新的container獲得釋放,所以該事件會觸發資源分配,也就是說,該事件是6個事件中最重要的事件,它會觸發資源調度器最核心的資源分配機制。
當前YARN支持內存和CPU兩種資源類型的管理和分配。當NodeManager啓動時,會向ResourceManager註冊,而註冊信息中會包含該節點可分配的CPU和內存總量,這兩個值都可經過配置選項設置,具體以下:
(1)yarn.nodemanager.resource.memory-mb
可分配的物理內存總量,默認是8*1024MB。
(2)yarn.nodemanager.vmem-pmem-ratio
每單位的物理內存總量對應的虛擬內存量,默認是2.1,表示每使用1MB的物理內存,最多可使用2.1MB的虛擬內存總量。
(3)yarn.nodemanager.resource.cpu-core(默認是8)
可分配的CPU總個數,默認是8
(4)yarn.nodemanager.vcores-pcores-ratio
爲了更細粒度的劃分CPU資源,YARN將每一個物理CPU劃分紅若干個虛擬CPU,默認值爲2。用戶提交應用程序時,能夠指定每一個任務須要的虛擬CPU個數。在MRAppMaster中,每一個Map Task和Reduce Task默認狀況下須要的虛擬CPU個數爲1,用戶可分別經過mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores進行修改(對於內存資源,Map Task和Reduce Task默認狀況下須要1024MB,用戶可分別經過mapreduce.map.memory.mb和mapreduce.reduce.memory.mb修改)。
(在最新版本2.1.0-beta中,yarn.nodemanager.resource.cpu-core和yarn.nodemanager.vcores-pcores-ratio兩個參數被遺棄,引入一個新參數yarn.nodemanager.resource.cpu-vcore,表示虛擬CPU個數,具體請閱讀YARN-782)
YARN對內存資源和CPU資源採用了不一樣的資源隔離方案。對於內存資源,爲了可以更靈活的控制內存使用量,YARN採用了進程監控的方案控制內存使用,即每一個NodeManager會啓動一個額外監控線程監控每一個container內存資源使用量,一旦發現它超過約定的資源量,則會將其殺死。採用這種機制的另外一個緣由是Java中建立子進程採用了fork()+exec()的方案,子進程啓動瞬間,它使用的內存量與父進程一致,從外面看來,一個進程使用內存量可能瞬間翻倍,而後又降下來,採用線程監控的方法可防止這種狀況下致使swap操做。對於CPU資源,則採用了Cgroups進行資源隔離。具體可參考YARN-3。
在YARN中,用戶以隊列的形式組織,每一個用戶可屬於一個或多個隊列,且只能向這些隊列中提交application。每一個隊列被劃分了必定比例的資源。
YARN的資源分配過程是異步的,也就是說,資源調度器將資源分配給一個application後,不會馬上push給對應的ApplicaitonMaster,而是暫時放到一個緩衝區中,等待ApplicationMaster經過週期性的RPC函數主動來取,也就是說,採用了pull-based模型,而不是push-based模型,這個與MRv1是一致的。
相比於MRv1中的資源調度器,儘管YANR的調度器也是插拔式的,但因爲YARN採用了事件驅動的模型,所以編寫起來更加複雜,難度也遠遠大於MRv1。
同MRv1同樣,YARN也自帶了三種經常使用的調度器,分別是FIFO,Capacity Scheduler和Fair Scheduler,其中,第一個是默認的調度器,它屬於批處理調度器,然後兩個屬於多租戶調度器,它採用樹形多隊列的形式組織資源,更適合公司應用場景。須要注意的是,這三種調度器採用的算法與MRv1中的徹底一致,只不過是根據YARN中資源調度器的對外接口從新實現了一遍,在此再也不贅述。
原創文章,轉載請註明: 轉載自董的博客
本文連接地址: http://dongxicheng.org/mapreduce-nextgen/yarnmrv2-resource-manager-resource-manager/