Hadoop YARN 調度器(scheduler) —— 資源調度策略
搜了一些博客,發現寫得最清楚的還是《Hadoop權威指南》,以下內容主要來自《Hadoop The Definitive Guide》 4th Edition 2015.3。
Hadoop YARN Scheduler
三個調度器
YARN提供了CapacityScheduler, FairScheduler, FifoScheduler三個調度器,繼承於AbstractYarnScheduler,Resource Manager通過調度器決定對提交application分配的資源大小。
CapacityScheduler首先將所有資源分配到hierarchical queue中,每個任務執行時指定對應的queue,使大任務不會占用整個集群的資源,通過對queue的資源管理提高整個集群的資源共享能力。通常會使小任務執行更快,大任務更慢。
Fair Scheduler 會在第一個任務運行時分配當前同級隊列的所有資源,當有其它任務運行時,回收前面任務運行時的部分資源(一般為運行完成的Container)用於其它任務。
至於FIFO,源碼裏都沒有描述,可能就是一般的先進先出了。
YARN默認使用CapacityScheduler,通過下面的屬性配置:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
YARN 動態資源分配
YARN 能夠動態申請資源,如MapReduce中reduce的container會在map過程結束後申請。但Spark On YARN的機制為申請固定的executor,而不動態改變已申請的資源。
YARN上新運行的任務能夠使用已運行任務回收的資源(如運行完Map task的container),甚至還能夠通過強行結束先前任務的container搶占資源。
Capacity Scheduler
CapacityScheduler重點解決多個組織共享集群資源,並保證每個組織自己的資源使用量。當自己的資源不足時能夠使用其它組織的空閑資源。
資源通過層級隊列(hierarchical queues)的形式進行組織,配置在etc/hadoop/capacity-scheduler.xml.
<!-- 隊列結構設置 -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>a,b</value>
<description>The queues at the this level (root is the root queue).
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.a.queues</name>
<value>a1,a2</value>
<description>The queues at the this level (root is the root queue).
</description>
</property>
<!-- 隊列能力設置 -->
<property>
<name>yarn.scheduler.capacity.root.a.capacity</name>
<value>40</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.b.capacity</name>
<value>60</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.a.a1.capacity</name>
<value>50</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.a.a2.capacity</name>
<value>50</value>
</property>
<!-- 最大能力占用 -->
<property>
<name>yarn.scheduler.capacity.root.a.maximum-capacity</name>
<value>75</value>
</property>
root
├── a 40%
| ├── a1 50%
| └── a2 50%
└── b 60%
上面的設置形成了如圖的hierarchical queues,並指定a隊列使用40%的資源,b隊列60%,a1 a2各占a隊列的50%,a隊列在b隊列資源空閑時,最高可占用集群75%的資源。
一些設置和特點
- 通過設置queue的maximum capacity能夠避免使用相鄰子隊列的所有資源。
- 改變文件後需要運行
$HADOOP_YARN_HOME/bin/yarn rmadmin -refreshQueues
- 子隊列能使用的最大資源為父隊列的資源
- 隊列上除了對資源的管理,還提供了運行的用戶、應用數量等的限制功能。
- 默認只支持內存,通過配置可以支持CPU
Fair Scheduler (公平調度器)
對比CapacityScheduler的主要區別: 任務提交時占用同一層隊列所有的資源 (Capacity Scheduler中只使用maximum-capacity限制下的其它隊列閑置的資源),另一個任務提交時,會回收先前任務的部分資源。
<allocations>
<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<queue name="a">
<weight>4</weight>
<schedulingPolicy>fifo</schedulingPolicy>
<queue name="a1" />
<queue name="a2" />
</queue>
<queue name="b">
<weight>6</weight>
</queue>
<queuePlacementPolicy>
<rule name="specified" create="false" />
<rule name="primaryGroup" create="false" />
<rule name="default" queue="a.a1" />
</queuePlacementPolicy>
</allocations>
上面的配置文件給出了一個如下圖的層級隊列。
root
├── a (權重4 因此占用總體40%的資源)
| ├── a1 沒有指定權重,因此與a2隊列平分a隊列40%的資源;隊列內部的多個應用使用fifo策略。
| └── a2
└── b (權重6 因此占用總體60%的資源)
向a1隊列中提交任務1時,首先會占用整個集群;向b隊列提交任務2時,會從任務1中回收60%的資源用於任務2;向a1隊列中繼續提交任務3時,會按fifo的策略使用a隊列的40%資源;向a2隊列提交任務4時,會從a1隊列的任務1、任務3中回收資源,使a1隊列資源和a2隊列相同。
在Hadoop Fair Scheduler的具體實現中,並沒有對每個application實現絕對公平的資源分配,而是針對同一級隊列內部的資源,隊列內部可以選擇其它的調度策略。並且使用weight參數,使相同層級的隊列資源根據weight分配而非直接平均,設置不同weight後並不“fair”。(實質上和CapacityScheduler類似,都是對層級隊列的管理,每一層的隊列之間資源存在共享,有博客提到FairScheduler在不斷的發展中已經能夠實現大部分CapacityScheduler的功能,兩者的功能越來越接近)
註意,Fair Scheduler會默認對每個用戶創建一個queue用於沒指定queue的任務,weight為1,因此要想忽略默認創建的用戶queue,需要將權重設置偏大。
隊列內部調度策略
每個隊列內使用一定的調度策略,常見的FIFO、FAIR和DRF。
FIFO(first in first out), 先提交的任務先分配資源。
FAIR (max-min fairness), 先把資源平均分配,某些任務如果有多出資源則將多出的資源分配給其它任務,對資源要求低的任務優先。
DRF(dominant resource fairness),解決有多種資源(CPU、內存等)同時考慮的分配問題,如一個CPU要求高內存要求低與一個CPU要求低內存要求高的應用。
Hadoop YARN 調度器(scheduler) —— 資源調度策略