(1)FIFO Scheduler
將所有的Applications放到隊列中,先按照作業的優先級高低、再按照到達時間的先后,為每個app分配資源。如果第一個app需要的資源被滿足了,如果還剩下了資源並且滿足第二個app需要的資源,那么就為第二個app分配資源,and so on。
優點:簡單,不需要配置。
缺點:不適合共享集群。如果有大的app需要很多資源,那么其他app可能會一直等待。
一個例子
上圖的示例:有一個很大的job1,它先提交,並且占據了全部的資源。那么job2提交時發現沒有資源了,則job2必須等待job1執行結束,才能獲得資源執行。
配置
FIFO Scheduler不需要配置
(2)Capacity Scheduler
CapacityScheduler用於一個集群(集群被多個組織共享)中運行多個Application的情況,目標是最大化吞吐量和集群利用率。
CapacityScheduler允許將整個集群的資源分成多個部分,每個組織使用其中的一部分,即每個組織有一個專門的隊列,每個組織的隊列還可以進一步划分成層次結構(Hierarchical Queues),從而允許組織內部的不同用戶組的使用。
每個隊列內部,按照FIFO的方式調度Applications。當某個隊列的資源空閑時,可以將它的剩余資源共享給其他隊列。
if there is more than one job in the queue and there are idle resources available, then the Capacity Scheduler may allocate the spare resources to jobs in the queue, even if that causes the queue’s capacity to be exceeded This behavior is known as queue elasticity.
配置
CapacityScheduler的配置文件etc/hadoop/capacity-scheduler.xml
說明:root隊列下面有兩個隊列,分別為prod(40%的容量,即使用40%的集群資源)和dev(60%的容量,最大的75% -> 說明即使prod隊列空閑了,那么dev最多只能使用75%的集群資源。這樣就可以保證prod中添加新的apps時馬上可以使用25%的資源)。
除了隊列的容量和層次,還可以指定單個用戶或者應用被分配的資源大小、同時可以運行的app數量、隊列的ACLs。
可以指定app要放在哪個隊列中。如果不指定,app將會被放在名字是 default的隊列中。
CapacityScheduler的隊列名字必須是層次結構最后的名字,比如eng。不能是root.dev.eng或者dev.eng。
一個例子
上圖的示例:有一個專門的隊列允許小的apps提交之后能夠盡快執行,注意到job1先提交,先執行時並沒有占用系統的全部資源(假如job1需要100G內存,但是整個集群只有100G內存,那么只分配給job1 80G),而是保留了一部分的系統資源。
(3)Fair Scheduler
FairScheduler允許應用在一個集群中公平地共享資源。默認情況下FairScheduler的公平調度只基於內存,也可以配置成基於memory and CPU。當集群中只有一個app時,它獨占集群資源。當有新的app提交時,空閑的資源被新的app使用,這樣最終每個app就會得到大約相同的資源。可以為不同的app設置優先級,決定每個app占用的資源百分比。FairScheduler可以讓短的作業在合理的時間內完成,而不必一直等待長作業的完成。
Fair Sharing: Scheduler將apps組織成queues,將資源在這些queues之間公平分配。默認情況下,所有的apps都加入到名字為“default“的隊列中。app也可以指定要加入哪個隊列中。隊列內部的默認調度策略是基於內存的共享策略,也可以配置成FIFO和multi-resource with Dominant Resource Fairness
Minimum Sharing:FairScheduller提供公平共享,還允許指定minimum shares to queues,從而保證所有的用戶以及Apps都能得到足夠的資源。如果有的app用不了指定的minimum的資源,那么可以將超出的資源分給別的app使用。
FairScheduler默認讓所有的apps都運行,但是也可以通過配置文件小智每個用戶以及每個queue運行的apps的數量。這是針對一個用戶一次提交hundreds of apps產生大量中間結果數據或者大量的context-switching的情況。
一個例子
示例1:大的任務job1提交並執行,占用了集群的全部資源,開始執行。之后小的job2執行時,獲得系統一半的資源,開始執行。因此每個job可以公平地使用系統的資源。當job2執行完畢,並且集群中沒有其他的job加入時,job1又可以獲得全部的資源繼續執行。
注意:job2提交之后並不能馬上就獲取到集群一半的資源,因為job2必須等待job1釋放containers。
一個例子
示例2:兩個用戶A和B。A提交job1時集群內沒有正在運行的app,因此job1獨占集群中的資源。用戶B的job2提交時,job2在job1釋放一半的containers之后,開始執行。job2還沒執行完的時候,用戶B提交了job3,job2釋放它占用的一半containers之后,job3獲得資源開始執行。
配置:
使用FairScheduler需要修改yarn-size.xml文件,創建allocation file,列出存在的隊列和各自的 weights and capacities
prod和dev的權重也可以設置成2和3。
dev下的兩個sub-queue沒有指定權重,則為1:1。
在設置權重時,需要考慮default queue和用戶命名的queue的權重,這些沒有在xml文件中指定,但是它們的權重都是1.
隊列還可以被配置minimum maximum Resources以及可以運行的最大的apps的數量
FairScheduler支持preemption(搶占),當queue占用的資源大於它應得的,那么調度器可以殺掉queue對應的containers,將yarn.scheduler.fair.preemption設置成true即可。
FairScheduler和CapacityScheduler的異同
相同:
(1)以隊列划分資源
(2)設定最低保證和最大使用上限
(3)在某個隊列空閑時可以將資源共享給其他隊列。
不同:
(1)Fair Scheduler隊列內部支持多種調度策略,包括FIFO、Fair(隊列中的N個作業,每個獲得該隊列1 / N的資源)、DRF(Dominant Resource Fairness)(多種資源類型e.g. CPU,內存 的公平資源分配策略)
(2)Fair Scheduler支持資源搶占。當隊列中有新的應用提交時,系統調度器理應為它回收資源,但是考慮到共享的資源正在進行計算,所以調度器采用先等待再強制回收的策略,即等待一段時間后入股仍沒有獲得資源,那么從使用共享資源的隊列中殺死一部分任務
(3)Fair Scheduler中有一個基於任務數量的負載均衡機制,該機制盡可能將系統中的任務分配到各個節點
(4)Fair Scheduler可以為每個隊列單獨設置調度策略(FIFO Fair DRF)
(5)Fair Scheduler由於可以采用Fair算法,因此可以使得小應用快速獲得資源,避免了餓死的情況。
Hierarchical queues with pluggable policies
FairScheduler支持層次隊列(hierarchical queues),所有隊列都從root隊列開始,root隊列的孩子隊列公平地共享可用的資源。孩子隊列再把可用資源公平地分配給他們的孩子隊列。apps可能只會在葉子隊列被調度。此外,用戶可以為每個隊列設置不同的共享資源的策略,內置的隊列策略包括 FifoPolicy, FairSharePolicy (default), and DominantResourceFairnessPolicy。
用戶可以通過繼承org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy實現自己定義的策略。
(4)Delay Scheduling&Dominant Resource Fairness
CapacityScheduler和FairScheduler都支持Delay Scheduling和DRF
不同的apps對CPU和內存的需求量不一樣,有的可能需要大量的CPU和一點點內存,有的可能正相反。這會使調度變得復雜。YARN解決的方法是Dominant Resource Fairness,即看app主要需要的資源是什么,用它作為該app對集群使用的度量。
參考:
(1)《Hadoop The Definitive Guide 4th》
(2)官方文檔
http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html
http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/FairScheduler.html