10.5 Fair Scheduler实现

Fair Scheduler[1]是Facebook开发的多用户调度器。与Capacity Scheduler类似,它以资源池(与队列一个概念)为单位划分资源,每个资源池可设定一定比例的资源最低保证和使用上限,同时,每个用户也可设定一定的资源使用上限以防止资源滥用;当一个资源池的资源有剩余时,可暂时将剩余资源共享给其他资源池。当然,Fair Scheduler也存在很多与Capacity Scheduler不同之处,主要体现在以下几个方面。

❑资源公平共享:在每个资源池中,Fair Scheduler可选择按照FIFO或者Fair策略为作业分配资源,其中Fair策略是一种基于最大最小公平算法[2]实现的资源多路复用方式,默认情况下,每个队列内部采用该方式分配资源。这意味着,如果一个队列中有两个作业同时运行,则每个作业可得到1/2的资源;如果三个作业同时运行,则每个作业可得到1/3的资源。

❑支持资源抢占:当某个资源池中有剩余资源时,调度器会将这些资源共享给其他资源池;而当该资源池中有新的作业提交时,调度器要为它回收资源。为了尽可能降低不必要的计算浪费,调度器采用了先等待再强制回收的策略,即如果等待一段时间后尚有未归还的资源,则会进行资源抢占:从那些超额使用资源的队列中杀死一部分任务,进而释放资源。

❑负载均衡:Fair Scheduler提供了一个基于任务数目的负载均衡机制。该机制尽可能将系统中的任务均匀分配到各个节点上。此外,用户也可以根据自己的需要设计负载均衡机制。

❑任务延时调度:Fair Scheduler提供了一种基于延时等待的调度机制以提高任务的数据本地性。该机制通过暂时减少个别作业的资源量而提高系统整体吞吐率。

❑降低小作业调度延迟:由于采用了最大最小公平算法,小作业可以优化获取资源并运行完成。

10.5.1 Fair Scheduler功能介绍

与Capacity Scheduler类似,Fair Scheduler也是一个多用户调度器,它同样添加了多层级别的资源限制条件以更好地让多用户共享一个Hadoop集群,比如队列资源限制、用户作业数目限制等。然而,由于Fair Scheduler增加了很多新的特性,因此它的配置选项更多。为了能够更详尽地了解Fair Scheduler的功能,我们从它的配置文件讲起。Fair Scheduler的配置选项包括两部分,其中一部分在mapred-site.xml中,另外一部分在自己的配置文件中,默认情况下为存放在conf目录下的fair-scheduler.xml。

1.配置文件mapred-site.xml

启用Fair Scheduler时,可在配置文件mapred-site.xml中增加以下几个配置选项(其中,mapred.jobtracker.taskScheduler是必填的,其他自选)。

❑mapred. jobtracker.taskScheduler:采用的调度器所在的类,即为org.apache.hadoop.mapred.FairScheduler。

❑mapred. fairscheduler.poolnameproperty:资源池命名方式,包含以下三种命名方式。

〇user.name:默认值,一个UNIX用户对应一个资源池。

〇group.name:一个UNIX用户组对应一个资源池。

〇mapred.job.queue.name:一个队列对应一个资源池。如果设置为该值,则与Capacity Scheduler一样。

❑mapred. fairscheduler.allocation.file:Fair Scheduler配置文件所在位置,默认是$HADOOP_HOME/conf/fair-scheduler.xml。

❑mapred. fairscheduler.preemption:是否支持资源抢占,默认为false。

❑mapred. fairscheduler.preemption.only.log:是否只打印资源抢占日志,并不真正进行资源抢占。打开该选项可用于调试。

❑mapred. fairscheduler.assignmultiple:是否在一次心跳中同时分配Map Task和ReduceTask,默认为true。

❑mapred. fairscheduler.assignmultiple.maps:一次心跳最多分配的Map Task数目,默认是-1,表示不限制。

❑mapred. fairscheduler.assignmultiple.reduces:一次心跳最多分配的Reduce Task数目,默认是-1,表示不限制。

❑mapred. fairscheduler.sizebasedweight:是否按作业大小调整作业权重。将该参数置为true后,调度器会根据作业长度(任务数目)调整作业权重,以让长作业获取更多资源,默认是false。

❑mapred. fairscheduler.locality.delay.node:为了等待一个满足node-local的slot,作业可最长等待时间。

❑mapred. fairscheduler.locality.delay.rack:为了等待一个满足rack-local的slot,可最长等待时间。

❑mapred. fairscheduler.loadmanager:可插拔负载均衡器。用户可通过继承抽象类LoadManager实现一个负载均衡器,以决定每个TaskTracker上运行的Map Task和Reduce Task数目,默认实现是CapBasedLoadManager,它将集群中所有Task按照数量平均分配到各个TaskTracker上。

❑mapred. fairscheduler.taskselector:可插拔任务选择器。用户可通过继承TaskSelector抽象类实现一个任务选择器,以决定对于给定一个TaskTracker,为其选择作业中的哪个任务。具体实现时可考虑数据本地性,推测执行等机制。默认实现是DefaultTaskSelector,它使用了JobInProgress中提供的算法,具体可参考第6章。

❑mapred. fairscheduler.weightadjuster:可插拔权重调整器。用户可通过实现WeightAdjuster接口编写一个权重调整器,以动态调整运行作业的权重。

2.配置文件fair-scheduler.xml

fair-scheduler. xml是Fair Scheduler的配置文件,管理员可为每个pool添加一些资源约束以限制资源使用。对于每个pool,用户可配置以下几个选项。

❑minMaps:最少保证的Map slot数目,即最小资源量。

❑maxMaps:最多可以使用的Map slot数目。

❑minReduces:最少保证的Reduce slot数目,即最小资源量。

❑maxReduces:最多可以使用的Reduce slot数目。

❑maxRunningJobs:最多同时运行的作业数目。通过限制该数目,可防止超量MapTask同时运行时产生的中间输出结果撑爆磁盘。

❑minSharePreemptionTimeout:最小共享量抢占时间。如果一个资源池在该时间内使用的资源量一直低于最小资源量,则开始抢占资源。

❑schedulingMode:队列采用的调度模式,可以是FIFO或者Fair。

管理员也可为单个用户添加maxRunningJobs属性限制其最多同时运行的作业数目。此外,管理员也可通过以下参数设置以上属性的默认值。

❑poolMaxJobsDefault:资源池的maxRunningJobs属性的默认值。

❑userMaxJobsDefault:用户的maxRunningJobs属性的默认值。

❑defaultMinSharePreemptionTimeout:资源池的minSharePreemptionTimeout属性的默认值。

❑defaultPoolSchedulingMode:资源池的schedulingMode属性的默认值。

❑fairSharePreemptionTimeout:公平共享量抢占时间。如果一个资源池在该时间内使用资源量一直低于公平共享量的一半,则开始抢占资源。

❑defaultPoolSchedulingMode:Pool的schedulingMode属性的默认值。

【实例】假设要为一个Hadoop集群增加三个资源池poolA、poolB和default,且规定普通用户最多可同时运行40个作业,但用户userA最多可同时运行400个作业,那么可在fair-scheduler.xml中进行如下配置:


<allocations>

<pool name="poolA">

<minMaps>100</minMaps>

<maxMaps>150</maxMaps>

<minReduces>50</minReduces>

<maxReduces>100</maxReduces>

<maxRunningJobs>200</maxRunningJobs>

<minSharePreemptionTimeout>300</minSharePreemptionTimeout>

<weight>1.0</weight>

</pool>

<pool name="poolB">

<minMaps>80</minMaps>

<maxMaps>80</maxMaps>

<minReduces>50</minReduces>

<maxReduces>50</maxReduces>

<maxRunningJobs>30</maxRunningJobs>

<minSharePreemptionTimeout>500</minSharePreemptionTimeout>

<weight>1.0</weight>

</pool>

<pool name="default">

<minMaps>0</minMaps>

<maxMaps>10</maxMaps>

<minReduces>0</minReduces>

<maxReduces>10</maxReduces>

<maxRunningJobs>50</maxRunningJobs>

<minSharePreemptionTimeout>500</minSharePreemptionTimeout>

<weight>1.0</weight>

</pool>

<user name="userA">

<maxRunningJobs>400</maxRunningJobs>

</user>

<userMaxJobsDefault>40</userMaxJobsDefault>

<fairSharePreemptionTimeout>6000</fairSharePreemptionTimeout>

</allocations>


[1]http://hadoop. apache.org/docs/stable/fair_scheduler.html

[2]Max-Min Fairness(Wikipedia):http://en. wikipedia.org/wiki/Max-min fairness