在Yarn里另一种资源调度器是Fair Scheduler公平调度器。它的基本思想是每个任务都是公平的。大家应该平分资源,当只有一个任务A在运行时,任务A占有100%的资源,如果这时来了一个任务B,则任务A和任务B占有50%的资源,如果任务B执行完成了,则任务A重新占有100%的资源。如下图:

当然公平调度器比上边说的要稍微复杂一点。

公平调度器也支持队列定义

公平调度器支持队列定义,队列可以有子队列。这样队列之间是按照公平的原则进行资源分配,队列内的任务或者子队列默认也是公平调度原则。但是队列内的任务或者子队列只能公平分配属于队列的资源。

从上图中可以看到公平调度器定义了两个队列,QueueA,QueueB。首先在QueueB里提交了job1。首先QueueA和QueueB公平分配资源。因为QueueA没有job,所以QueueB分得100%的资源,然后QueueB内只有job1一个任务,所以job1分得所有资源。
然后在QueueA提交了job2。这时QueueA和QueueB各分得50%的资源,然后QueueA里有一个job2,QueueB里有一个job1。因为每个Queue里只有一个job,所以job1,job2各自独占自己所在Queue的所有资源。
然后在job1,job2还在执行期间,又在QueueA提交了job3。这时QueueA,QueueB都有job在执行,所以QueueA和QueueB各自分得50%资源,job2和job3平分自己所在QueueA的资源,也就是分得整个系统资源的25%。QueueB只有一个job1,所以job1占有QueueB的所有资源,也就是整个系统资源的50%。

没有绝对的公平

世界上没有绝对的公平,在Yarn里也不例外。你可以定义你认为的公平,也就是每个队列在分配系统资源时的比重。比如你将QueueA和QueueB的比重这时为2:3。这时如果QueueA和QueueB内各有一个job在执行,那么QueueA分得资源是系统的40%,QueueB分得60%。

如何配置

首先我们需要在yarn-site.xml里指定Yarn使用的资源调度器


<property>
    <name>yarn.resourcemanager.scheduler.class</name>
    <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>

之前我们在看容量调度器时在hadoop安装目录下有一个etc/hadoop/capacity-scheduler.xml文件,但是在同样位置并没有fair-scheduler.xml。我们可以自己建立一个fair-scheduler.xml,放到该目录下,其实这个文件只要在你提交yarn程序的classpath里就可以。如果你在yarn-site.xml里设置了我们使用公平调度器,但是没有这个配置文件,那么系统会为每个提交job的用户创建一个队列。并且队列内默认也是公平调度器。


<allocations>
   <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<queue name="prod">
  <weight>40</weight>
  <schedulingPolicy>fifo</schedulingPolicy>
</queue>
<queue name="dev">
   <weight>60</weight>
   <queue name="eng" />
   <queue name="science" />
</queue>
<queuePlacementPolicy>
   <rule name="specified" create="false" />
   <rule name="primaryGroup" create="false" />
     <rule name="user" create="false" />
   <rule name="default" queue="dev.eng" />
</queuePlacementPolicy>
</allocations>

defaultQueueSchedulingPolicy参数指定了公平调度器内各个队列默认的调度策略。然后我们可以看到定义了两个队列prod和dev。而且prod的权重为40,dev的权重为60。如果不指定权重。就行dev下边的两个子队列eng和science,他们的权重默认是相等的。还有一个要注意的是prod队列里指定了自己的调度策略为fifo。而dev队列会使用之前defaultQueueSchedulingPolicy参数定义的公平调度策略。而容量调度器内只能是fifo,是不能配置的。

最为特别的是queuePlacementPolicy。这里定义的是来了一个job如何匹配它所在的Queue。每个rule可以定义不同的规则,从上向下如果匹配一条就退出。rule的name为specified是第一条,它的意思是用户指定的队列。后边的false表明如果用户指定的队列不存在,我们并不创建新的队列。如果为true将会创建一个新的用户指定的队列,队列权重为1. 第二条是检查用户所在的组为名的队列,如果不存在也不创建,第三条类似,它检查是否存在以用户名存在的队列。最后一条用来兜底,它将用户提交的任务放到dev.eng队列里。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: