原文:http://hadoop.apache.org/docs/r2.6.4/hadoop-yarn/hadoop-yarn-site/FairScheduler.html
介绍
公平调度是一种对于全局资源,对于所有应用作业来说,都均匀分配的资源分配方法。YARN有能力调度多种资源类型。默认情况,公平调度器FairScheduler基于内存来安排公平调度策略。也可以配置为同时基于内存和CPU来进行调度,这样情况下需要使用由Ghodsi开发的Dominant Resource Fairness进行。当只有一个单一应用作业运行时,这个应用可以独占整个集群。当其他应用作业提交到集群时,空出来的资源将分配给新的应用,最终所有的应用作业会平分集群资源。不像Hadoop的默认调度器,它只将任务构造一个应用队列,公平调度器会在不饿死长周期作业的同时,优先让短周期作业先运行完成。在一组用户中共享集群也是合理的。最终,公平调度策略可以和应用优先级结合起来工作,优先级是一组权重值,资源会按照这个权重比例来分配给每个应用。
调度器将所有的应用作业组织为队列,在这些队列之间公平的共享资源。默认情况下,所有用户共享一个单一的队列,叫做"default"。 如果一个应用在一个容器资源请求中列出了一个队列名,那么这个请求会被提交到这个队列。同样通过配置基于用户名来分配队列也是合理的。在每个队列内,一个调度策略是在所有运行中的应用之间共享资源。默认的是基于内存的公平调度,当然FIFO和使用Dominant Resource Fairness的多资源调度也是可以配置支持的。队列可以是一个层级排布的分布情况,这样可以划分资源并配置权重来按照特定比例来共享集群。
为了提供公平分享策略,FairScheduler允许保障性的分配最小资源到队列,这对于保证特定用户、组或者生产应用作业能获取到足够资源非常有帮助。当一个队列包含应用作业时,这个队列就有一份最小共享资源。但是当这个队列不再需要完整的保障性的资源时,多余的部分资源会被分配给其他运行中的应用中。这样做保障了队列的容量(虽然它们已不再包含运行中的作业)同时又高效的利用了集群资源。
FairScheduler允许所有的应用按照默认配置运行,同时也支持通过配置文件来限制每个用户每个队列的运行作业数。这对于一个用户必须一次提交成百上千的应用作业是有帮助的,换句话说,当一次需要提交很多作业时这个非常有效,因为这种情况下会造成创建很多的中间数据结果以及很多的上下文切换。限制运行的应用作业数,不会导致任何的已提交作业失败,只会让这些作业在调度器队列中等待直到某些用户的更早的作业结束。
使用可插拔策略的层级队列
公平调度器支持层级队列。所有的队列都衍生自一个叫做“root”的队列。可用的资源在根队列的子队列中使用典型的公平调度方式来分配。接下来,子队列再将获取到的资源以同样的公平策略分配给它们的子队列。所有的应用作业都只会被调度到叶子队列。队列可以被声明为其他队列的子队列,通过配置公平调度分配文件,将其配置到对应的父队列的调度配置文件中。
一个队列的名字以其父队列开始,逐个用英文句号分隔。所以一个队列父队列是root,自己叫queue1,那么它的名字就是root.queue1,同理一个队列叫queue2,其父队列是parent1,那么就叫做root.parent1.queue2。当被别的队列引用时,root部分是可选的,所以刚才的例子也可以简写为queue1和parent1.queue2。
公平调度器也支持为每个队列设置不同的自定义的策略来按照用户的意愿来分配队列资源。自定义策略通过扩展org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy
来实现。FifoPolicy, FairSharePolicy (默认的)和DominantResourceFairnessPolicy是几个内建的可供选用的策略。
在MR1版本Hadoop调度中是不支持特定的add-on的。
自动分配应用作业到队列
FairScheduler允许管理员来配置策略从而自动将提交的应用作业分配到合适的队列。这种分配可以依赖提交者的用户和组以及应用请求提交到的目标队列。一个策略一般包含一组规则,对于一个即将到来的应用作业,这组规则顺序的生效来进行分类。每条规则要么分配一个作业到队列,要么拒绝它,或者继续运行下一条规则。根据分配文件格式的不同来配置这些策略。
安装
在yarn-site.xml文件中设置属性来配置使用FairScheduler:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
配置
配置FairScheduler一般需要配置两个文件。首先调度器相关的选项可以在yarn-site.xml文件中配置。其次,大多数情况下用户希望创建一个分配文件来列出哪些队列用来分配以及对应的权重和容量。这个分配文件会每10秒钟重新加载一次,从而支持运行时配置变更。
yarn-site.xml中的配置属性
-
yarn.scheduler.fair.allocation.file
- 分配文件的路径地址。分配文件是一个XML文件来描述队列和队列的属性以及特定的策略。这个文件必须是一个XML格式的文件。如果配置一个相对路径,那么该文件会在classpath中被搜索到。默认是fair-scheduler.xml。
-
yarn.scheduler.fair.user-as-default-queue
- 是否使用用户名关联分配的默认队列名称,如果是false或者未设置,所有的作业都有一个共享的默认队列,叫做default。默认是true。如果队列分配策略在分配文件中配置过,那么这个属性会被忽略。
-
yarn.scheduler.fair.preemption
- 是否抢占。默认false。
-
yarn.scheduler.fair.preemption.cluster-utilization-threshold
- 当抢占式配置后,配置使用阈值。该阈值计算是按照所有资源的容量使用量的最大比例来算的。默认是0.8f。
-
yarn.scheduler.fair.sizebasedweight
- 是否分配资源给独立的作业,基于作业的size而不是均等的分配所有的资源。设置为true时,应用的权重通过1+请求资源内存大小的自然对数来计算。默认是false。
-
yarn.scheduler.fair.assignmultiple
- 是否允许在一次心跳中进行多次容器分配。默认是false。
-
yarn.scheduler.fair.max.assign
- 如果上个属性设置为true,这个属性明确一次心跳中能分配的最大的容器数。默认是-1,表示没有限制。
-
yarn.scheduler.fair.locality.threshold.node
- 对于特定node上请求容器的应用作业,该属性代表了自从上次容器分配等待调度到其他节点node上的机会的次数。表示为0到1之间的一个浮点数,该数字表达了集群规模的比例,代表了向上传递的调度机会数。默认值是-1.0,代表不传递任何调度机会。
-
yarn.scheduler.fair.locality.threshold.rack
- 对于特定rack上请求容器的作业,该属性代表了自从上次容器分配等待调度到其他rack上的机会的次数。表示为0到1之间的一个浮点数,该数字表达了集群规模的比例,代表了向上传递的调度机会数。默认值是-1.0,代表不传递任何调度机会。
-
yarn.scheduler.fair.allow-undeclared-pools
- 如果为true,新的队列可以在作业提交时创建,无论是提交者指定的应用作业的队列还是default的队列。如果为false,应用作业在任何时间都会被分配到一个没有在分配文件张声明过的队列中,相反就只会分配到default队列。该属性默认是true。如果队列分配策略在分配文件中设置过,那么这个属性失效。
-
yarn.scheduler.fair.update-interval-ms
- 锁定调度器和重新计算资源分配和需求,检查是否有抢占的时间间隔属性。默认是500ms。
分配文件格式Allocation file format
分配文件必须是XML格式。格式包含5个元素类型:
-
队列元素 标识队列用的。队列元素可以有一个可选的属性type,当设置为parent时表示队列是一个parent队列。当想创建一个父级队列,但是又没有叶子节点队列时,这个属性很有用。每个队列元素可能包含如下的属性:
- 最小资源minResources: 队列授予的最小资源,表示为"X mb, Y vcores"这样的格式。对于单一资源的公平策略,vcores值是忽略无效的。如果一个队列的最小资源满足不了,那么它将会被供给足够的资源直到同一个父队列下有其他队列加入。在单一资源公平策略下,一个队列的内存使用低于其最小资源将被认为是未满足的。在dominant resource fairness调度策略下,一个队列的dominant资源相对于集群容量的使用量如果低于其最小资源将被认为是未满足的。如果在此条件下多个队列是为满足的,资源选择分配给拥有最小资源使用比例的队列。注意一种情况,在作业提交时,具备低于最小资源条件的队列不会立刻获取最小的资源,因为已经在运行的作业可能正在使用那些资源。
- 最大资源maxResources: 一个队列允许分配的最大资源,表示为"X mb, Y vcores"。对于单一资源的公平策略,vcores值是忽略无效的。不会出现给一个队列分配容器能超过这个资源限制的情况。
- 最大运行应用数maxRunningApps: 队列运行最大的应用数限制。
- 最大AM资源maxAMShare: 队列中可用于运行ApplicationMaster的资源比例限制。该属性只能被用在叶子队列上。举个例子,如果设置为1.0f,那么这个叶子队列的ApplicationMaster可以使用100%的资源,包括内存和CPU。如果设置为-1.0f会disable这个属性,ApplicationMaster资源不会被检测。默认是0.5f。
- 权重weight: 不按照比例来分享集群资源。权重默认是1,如果一个队列的权重设置为2,那么它相较其他默认权重的队列来说,会收到近似2倍的资源。
- 调度策略schedulingPolicy: 设置队列的调度策略。允许的值是"fifo"/"fair"/"drf"或者其他任意class继承了org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy。默认是fair。如果设置了fifo,较早完成的提交将优先分配容器,但是较晚提交的作业可能会在较早的提交满足后且集群有足够的资源时并行执行。
- 提交应用的ACL aclSubmitApps: 允许提交应用作业到队列的用户或组列表。具体配置参看ACL一节。
- 管理应用的ACL aclAdministerApps: 允许管理应用作业到队列的用户或组列表。当前唯一支持的管理操作是杀死应用。具体配置参看ACL一节。
- 最小资源抢占超时时间minSharePreemptionTimeout: 当队列低于最小资源限制时,触发容器抢占其他队列的超时时间限制。如果不设置,队列从父队列继承。
- 公平资源抢占超时时间fairSharePreemptionTimeout: 当队列低于其公平资源阈值时,触发容器资源抢占其他队列的超时时间限制。如果不设置,队列从父队列继承。
- 公平资源抢占阈值fairSharePreemptionThreshold: 队列公平资源抢占阈值。如果队列在等待了fairSharePreemptionTimeout的时间后仍然没有收到fairSharePreemptionThreshold*fairShare大小的资源,它将允许抢占其他队列的容器资源。如果不设置,队列从父队列继承。
- 用户元素,表示了独立用户的行为设置。可以包含一个属性:maxRunningApps,表示对于特定用户限制其运行作业的个数。
- 用户最大应用数默认元素,如果用户的运行应用的数目没有限制,这个配置设置了对于任意用户能够运行应用的默认数目限制。
- 默认公平资源抢占超时时间,设置了root队列的公平资源抢占超时时间;会被root队列的fairSharePreemptionTimeout属性覆盖。
- 默认最小资源抢占超时时间,设置了root队列的最小资源抢占超时时间;会被root队列的minSharePreemptionTimeout属性覆盖。
- 默认公平资源抢占阈值,设置了root队列的公平资源抢占阈值;会被root队列的fairSharePreemptionThreshold属性覆盖。
- 队列最大应用数默认值,设置了队列的默认运行应用限制;会被各个队列自己的maxRunningApps属性覆盖。
- 队列最大ApplicationMaster资源默认值,设置了队列的默认AM资源限制;会被各个队列的maxAMShare属性覆盖。
- 默认队列调度策略,设置了队列的默认调度策略;会被每个声明了schedulingPolicy属性的队列的值覆盖。默认是fair。
-
队列分配策略,包含了一组规则元素来告诉调度器如何分配应用作业到队列。规则按照列表的顺序来生效。规则也可能接受参数。所有的规则接受"create"参数,该参数说明规则是否可以创建新队列。"Create"默认是true;如果设置为false,规则会将应用作业分配到没有在分配文件中列出的队列中,规则继续执行下一条。最后一条规则必须是一个没有触发继续执行的规则。合法的规则将是:
- specified: 应用作业将分配到它所请求的队列中去。如果应用没有请求指定队列,比如它声明的是default,那么规则继续。
- user: 应用作业将被分配到提交者用户名对应的队列中去。
- primaryGroup: 应用被分配到提交者用户所在主要group的名字对应的队列中去。
- secondaryGroupExistingQueue: 应用作业被分配到提交者用户所在的Secondary group的名字对应的队列中去。第一个匹配Secondary group名字的配置的队列将被选中。
- nestedUserQueue : 应用作业会分配到用户所在的嵌套规则队列下的队列中去。该规则和'user'规则很像,不同之处在于'user'规则是应用到root队列的,而嵌套用户队列可以创建到任意的parent队列下。注意该规则只会在嵌套规则返回一个父级队列时生效。用户可以通过设置队列的'type'属性为'parent'来配置一个父级队列,也可以配置那个队列有至少一个叶子队列来使其成为父级队列。具体参见下面的例子。
- default: 应用作业会被分配到默认规则声明了'queue'属性的队列中去。如果'queue'属性没有设定,应用作业被分配到'root.default'队列。
- reject: 应用作业被拒绝。
一个例子:
<?xml version="1.0"?>
<allocations>
<queue name="sample_queue">
<minResources>10000 mb,0vcores</minResources>
<maxResources>90000 mb,0vcores</maxResources>
<maxRunningApps>50</maxRunningApps>
<maxAMShare>0.1</maxAMShare>
<weight>2.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
<queue name="sample_sub_queue">
<aclSubmitApps>charlie</aclSubmitApps>
<minResources>5000 mb,0vcores</minResources>
</queue>
</queue>
<queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>
<!—- Queue 'secondary_group_queueue' is a parent queue and may have
user queues under it -->
<queue name="secondary_group_queue" type="parent">
<weight>3.0</weight>
</queue>
<user name="sample_user">
<maxRunningApps>30</maxRunningApps>
</user>
<userMaxAppsDefault>5</userMaxAppsDefault>
<queuePlacementPolicy>
<rule name="specified" />
<rule name="primaryGroup" create="false" />
<rule name="nestedUserQueue">
<rule name="secondaryGroupExistingQueue" create="false" />
</rule>
<rule name="default" queue="sample_queue"/>
</queuePlacementPolicy>
</allocations>
注意原始的FairScheduler的向后兼容性,"queue"元素可以被"pool"元素来替代。
队列ACL (ACLs)
队列的ACL允许管理员来控制哪些人可以操控队列。ACL是通过配置aclSubmitApps和aclAdministerApps属性来实现的,这些属性都可以被设置到每个队列去。当前唯一支持的管理操作就是杀死应用作业。任何可以管理队列用户也可以提交作业到队列。ACL属性以"user1,user2 group1,group2"或者 " group1,group2"的形式存在。当队列操作的用户或组在该队列的ACL,或者在该队列祖先队列的ACL中,那么该操作可以执行。因此如果queue2在queue1下面,而user1在queue1的ACL中,user2在queue2的ACL中,那么两个用户都可以提交作业到queue2。
注意:ACL中的分隔符是空格。声明只有组的ACL,起始字符需要是一个空格。
root队列的ACL默认是"*",以为ACL是向下传递的,也就是说任何人都是可以提交和杀死每一个队列的应用作业的。要开启严格的访问控制,需要修改root队列的ACL不是默认的星号。
管理
公平调度器通过以下一系列机制来支持运行时的管理:
运行时修改配置
通过编辑分配文件,运行是可以修改最小资源,限制,权重,抢占超时和队列调度策略等属性。调度器会在文件修改后10-15秒重新加载配置文件。
通过web界面监控
当前的作业,队列和公平资源都可以通过ResourceManager的web界面查看,地址是http://ResourceManager URL/cluster/scheduler。
队列的以下属性可以在web界面看到:
- 使用的资源 - 分配给队列的所有资源总和。
- 活动的应用作业数 - 队列中至少接受到一个容器资源的应用作业数。
- 挂起的应用作业数 - 队列中还没有收到容器资源的应用作业数。
- 最小资源 - 配置到队列的保证的最小资源数。
- 最大资源 - 配置到队列的最大资源数。
- 公平资源 - 队列的公平资源。当其他队列不使用时队列可以被分配超过公平资源限制的资源。一个队列的资源消耗低于其公平资源的话是不会被抢占的。
ResourceManager的web界面还会额外的显示每个应用作业的信息,其中也包括了应用的公平资源。
队列之间移动作业
FairScheduler支持移动一个正在运行的作业到其他队列。这对于把重要的作业移动到高优先级队列很有用,反之也一样。可以通过运行"yarn application -movetoqueue appID -queue targetQueueName"命令来移动应用。
当一个应用作业被移动到一个队列,它已有的分配资源会被计入到新的队列的资源分配中去,这样做的目的是保证公平。如果目标队列的maxRunningApps或者maxResources限制与要移动的作业冲突,那么作业移动会失败。