参考资料:
http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/FairScheduler.html
http://han-zw.iteye.com/blog/2322189 (转载其部分内容)
2.队列分层
3.配置
3.1配置yarn-site.xml
3.2 Allocation file格式
3.3 队列访问控制列表
4.管理
4.1 运行时修改配置
4.2通过web UI进行监控
4.3队列间移动应用程序
1.介绍
FairScheduler是yarn的一个调度器,支持多用户并行执行任务.默认情况下, FairScheduler只对内存执行调度管理,需要对CPU也进程调度管理的话使用Ghodsi et al的"Dominant Resource Fairness"(CDH5.7似乎已经支持CPU调度).特点:
- 允许资源共享,即当一个APP运行时,如果其它队列没有任务执行,则可以使用其它队列(不属于该APP的队列),当其它队列有APP需要资源时再将占用的队列释放出来.所有的APP都从资源队列中分配资源.
- 默认情况下,所有任务使用一个队列default;
- 如果任务指定了一个队列,则在该队列中提交任务.
- 可以根据提交任务的用户名来分配队列.
- 可以设置队列最小资源,保证用户可以启动任务.
- 当队列中有任务,该队列将至少获得最小资源.当队列资源使用不完时,可以给其它队列使用.
- 默认不限制每个队列和用户可以同时执行的app数量.可以配置来限制队列和用户并行执行的app数量.限制并行执行APP数量不会导致任务提交失败,超出的app会在队列中等待.
- 当队列不能满足最小资源时,可以从其它队列抢占.
2.队列分层
FairScheduler支持子队列,所有队列的父队列是"root"队列.子队列又可以分配子队列(在allocation file里添加).子队列继续父队列的名字,如'q1'这个子队列的名字实际上是'root.q1',同样,如果q2是q1的子队列,则q2的名字为'root.q1.q2'.此外,用户可以自定义队列的资源分配情况,需要继承"org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy"这个类.FifoPolicy\FairSharePolicy\DominantResourceFairnessPolicy(DRF)三种策略已经保含在FairScheduler中随时可以使用
.
3.配置
有两个配置文件yarn-site.xml和allocation file,前者用来FairScheduler的核心参数,后面配置子队列\用户等参数.
3.1配置yarn-site.xml
参数 | 默认值 | 说明 |
---|---|---|
yarn.scheduler.fair.allocation.file | Hadoop conf directory | allocation file的路径.XML格式,默认名字是fair-scheduler.xml |
yarn.scheduler.fair.user-as-default-queue |
true | 当没有指定队列名时,是否使用用户名做为应用程序的队列名.设置为false或不设置,则所有未知队列的应用程序就会使用default队列. |
yarn.scheduler.fair.preemption | false | 当队列没有达到分配的最小资源时,是否抢很抢占其它队列的资源. |
yarn.scheduler.fair.preemption.cluster-utilization-threshold | 0.8f | 启用资源抢占后,可以使用的集群最大资源量.抢占优先级最低,id最大的container |
yarn.scheduler.fair.sizebasedweight | false | 是否根据任务需要的资源权重来分配资源.默认一个队列中所有的任务用的资源都是相同的.设置为true,app的权重是app的所有请求内存的自然对数加权,除以以2为底的自然对数。 |
yarn.scheduler.fair.assignmultiple | false | 批量分配资源,是否允许一次心跳中进行多容器分配 |
yarn.scheduler.fair.dynamic.max.assign | true | 开启批量分配资源后,一次可以分配未分配资源的一半给容器 |
yarn.scheduler.fair.max.assign | -1 | 如果开启批量而yarn.scheduler.fair.dynamic.max.assign又设置为true时,一次分配的container的个数,默认分-1不开启指分配 |
yarn.scheduler.fair.locality.threshold.node | -1 | 在特定节点上申请资源的程序,当本节点无法满足资源申请时,忽略转移到其它节点上申请的概率因子,默认是-1,不忽略任务机会 |
yarn.scheduler.fair.locality.threshold.rack | -1 | 同上,节点改为机架 |
yarn.scheduler.fair.allow-undeclared-pools |
true | 在任务提交时是否允许创建不存在的新队列.当为false时,任务指定了不存在的队列则将在default中执行 |
yarn.scheduler.fair.update-interval-ms | 500ms | 调度器重新计算资源的时间间隔 |
yarn.scheduler.increment-allocation-mb | 1024mb | 调度器分配的内存增量单位,每次至少新增加这么多内存,四舍五入 |
yarn.scheduler.increment-allocation-vcores | 1 | 同上,增加的核心数 |
3.2 Allocation file格式
(以下内容转载自http://han-zw.iteye.com/blog/2322189)
分配文件必须是XML格式。格式包含5类元素:
队列元素:描述队列。队列元素可以设定一个可选的属性‘type’,当它设置为‘parent’时表示它是一个父队列。当我们想创建一个父队列但是不想配置任何子队列时可以采用这种方式。每个队列元素可以包含下面的属性:
-
- minResources: 队列有权享有的最小资源,采用"X mb, Y vcores”"的形式。对于单一资源公平策略,vcores的值将被忽略。如果一个队列的最小共享未能得到满足,那么它将会在相同parent下其他队列之前获得可用资源。在单一资源公平策略下,一个队列如果它的内存使用量低于最小内存值则认为是未满足的。在DRF策略下,如果一个队列的主资源是低于最小共享的话则认为是未满足的。如果有多个队列未满足的情况,资源分配给相关资源使用量和最小值之间比率最小的队列。注意一点情况,有可能一个队列处于最小资源之下,但是在它提交application时不会立刻达到最小资源,因为已经在运行的job会使用这些资源。
- maxResources: 一个队列允许的最大资源,采用“X mb, Y vcores”的形式。对于单一资源公平策略,vcores的值会被忽略。一个队列永远不会分配资源总量超过这个限制。
- maxRunningApps: 限制队列一次运行的apps数量。
- maxAMShare:限制队列用于运行Application Master的资源比例。这个属性只能用于叶子队列。比如,如果设置为1.0f,那么在这个队列的AMs可以占用100%的内存和CPU的公平共享。这个值为-1.0f将会禁用该特性并且amShare不会进行校验。默认值是0.5f。
- weight: 与其他队列非比例的分享集群。权重默认是1,权重是2的队列将会收到接近默认权重2倍的资源。
- schedulingPolicy:任一队列都可以设置调度策略。允许的值包括“fifo”,“fair”,“drf”或者其他任何继承org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy的类。默认是“fair”。如果为"fifo",提交时间较早的apps优先分配容器,但是如果集群在满足较早的apps请求之后剩余足够的空间,提交较晚的apps可能并发运行。
- aclSubmitApps:可以提交apps到队列的用户或者组的列表。要获得更多信息可以参考下面的ACLs部分,关于列表的格式和ACLs如何发挥作用。
- aclAdministerApps:可以管理队列的用户或者组列表。当前唯一的管理动作就是杀死应用程序。要获得更多信息可以参考下面的ACLs部分,关于列表的格式和ACLs如何发挥作用。
- minSharePreemptionTimeout:队列处在最小共享之下,在尝试抢占其他队列的资源之前的秒数。如果不设置,队列将会总其父队列继承这个值。
- fairSharePreemptionTimeout:队列处在最小公平共享阈值之下,在尝试抢占其他队列的资源之前的秒数。如果不设置,队列将会总其父队列继承这个值。
- fairSharePreemptionThreshold:队列的公平共享抢占阈值。如果队列等待fairSharePreemptionTimeout之后没有接收到fairSharePreemptionThreshold*fairShare的资源,它被允许从其他队列抢占资源。如果不设置,队列将会总其父队列继承这个值。
User elements:设置对单独用户行为的管理。它们可以包含单一属性:maxRunningApps,对特定用户可以运行的apps的数量限制。
A userMaxAppsDefault element:设置任意用户(没有特定限制的用户)运行app的默认最大数量限制。
A defaultFairSharePreemptionTimeout element:设置root队列的公平共享抢占的默认超时时间;可以被root队列下的fairSharePreemptionTimeout 设置覆盖。
A defaultMinSharePreemptionTimeout element:设置root队列的默认最小共享抢占超时时间;可以被root队列下minSharePreemptionTimeout覆盖。
A defaultFairSharePreemptionThreshold element:设置root队列的公平共享抢占的默认阈值;可以被root队列下的fairSharePreemptionThreshold 覆盖。
A queueMaxAppsDefault element:设置队列的默认运行app数量限制;可以被任一队列的maxRunningApps元素覆盖。
A queueMaxAMShareDefault element:设置队列的默认AM共享资源限制;可以被任一队列的maxAMShare 元素覆盖。
A defaultQueueSchedulingPolicy element:设置队列的默认调度策略;可以在任一队列中设置schedulingPolicy 进行覆盖该默认值。默认值为“fair”。
-
A queuePlacementPolicy element:包含一个Rule元素列表用于告诉调度器如何放置app到队列。Rule生效顺序与列表中的顺序一致。Rule可以含有参数。所有Rule接受"create"参数,用于标明该规则是否能够创建新队列."Create"默认值为true;如果设置为false并且Rule要放置app到一个allocations file没有配置的队列,那么继续应用下一个Rule。最后的Rule绝不能执行Continue。合法的规则是:
- specified:app放置到它请求的队列。如果没有请求队列,例如它指定"default",执行continue。如果app请求队列以英文句点开头或者结尾,例如 “.q1” 或者 “q1.” 将会被拒绝.
- user:app按照提交用户名放置到同名的队列。用户名中的英文句点将会被“dot”替换,如对于用户"first.last"的队列名是"first_dot_last".
- primaryGroup:app放置到与提交用户primary group同名的队列。用户名中的英文句点将会被“dot”替换,如对于组"one.two"的队列名是"one_dot_two".
- secondaryGroupExistingQueue:app放置到与提交用户所属的secondary group名称相匹配的队列。第一个与配置相匹配的secondary group将会被选中。组名中的英文句点会被替换成“dot”,例如用户使用“one.two”作为他的secondary groups将会放置到“one_dot_two”队列,如果这个队列存在的话。
- nestedUserQueue: app放置到根据队列中嵌套规则建议的用户名同名的队列中。这有些类似于UserRule,在‘nestedUserQueue’规则中不同的是用户队列可以创建在任意父队列下,而'user'规则只能在root队列下创建用户队列。有一点需要注意,nestedUserQueue 规则只有在嵌入规则返回一个父队列时才会生效。用户可以通过设置 队列的‘type’属性为 ‘parent’ 来配置父队列,或者在队列下至少配置一个叶子。
- default: app放置到default规则中指定的 ‘queue’属性对应的队列。如果 ‘queue’属性没有指定,app放置到 ‘root.default’ 队列.
- reject:拒绝app.
以下给出 allocation file的一个样例:
<pre style="font-family: monospace; font-size: 1em;"><?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_queue' 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>
</pre>
为了保持与原始的FairScheduler的向后兼容,“queue”元素可以用名为“pool”的元素替代.
3.3 队列访问控制列表
访问控制列表(ACLs)允许管理员控制谁能对特定队列执行操作。这些用户通过aclSubmitApps 和aclAdministerApps属性配置,可以设置在每个队列上。当前唯一支持的管理性操作就是杀死app。任何能够管理管理的人也都可以向该队列提交app.这些属性的值像 “user1,user2 group1,group2” 或者“ group1,group2”的格式。如果用户或者组是在队列的ACLs中或者在这个队列的任意祖先的ACLs中,那么他对该队列的操作是被允许的。所以,如果queue2 在queue1内部,并且user1 在queue1的ACL中,user2 在queue2的ACL中,那么两个用户都可以向queue2提交app.
备注:分隔符是空格。要只是指定ACL组,该值需要以空格开头.
root队列的ACLs默认是"",因为ACLs是向下传递的,意思是每个用户都可以对每一个队列提交和杀死App。要启动严格的方访问,修改root队列的ACL为除""之外的其他值.
4.管理
Fair Scheduler通过一些机制提供运行时的管理功能:
4.1 运行时修改配置
通过编辑allocation file可以在运行时完成修改最小共享,资源限制,权重,超时抢占以及队列调度策略等。调度器会每个10-15秒重载修改后的该配置文件.
4.2通过web UI进行监控
当前应用、队列以及公平共享都可以通过ResourceManager的web UI查看,地址在http://ResourceManager URL/cluster/scheduler。
在web UI上可以看到每个队列的以下字段:
Used Resources-队列已经分配的容器的资源之和。
Num Active Applications-队列中已经接受到至少一个容器的应用程序数量。
Num Pending Applications-队列中还没有接受任何一个容器的应用程序的数量。
Min Resources-配置的授予队列的最小资源。
Max Resources - 配置的队列允许的最大资源.
Instantaneous Fair Share - 队列的资源的瞬时公平共享。这些共享只考虑活动的队列(那些有运行中程序的),而且被调度决策所使用。当其他队列没有使用某些资源时,队列可以被分配到超过他shares的资源。一个队列的资源消费处在或者低于它的瞬时公平份额将不会有容器被抢占。
Steady Fair Share-队列的固定公平份额,无论这些队列是否活跃。他们很少被计算和修改,除非配置或者容量发生变化。他们意思是提供资源可视化。
4.3队列间移动应用程序
Fair Scheduler 支持移动一个运行中的应用程序到另外一个队列。这个可以用于移动一个重要的应用程序到较高优先级队列,或者移动一个不重要的应用程序到一个较低优先级的队列。通过运行 yarn application -movetoqueue appID -queue targetQueueName可以移动运行中的应用程序。
当应用程序移动到一个队列,出于公平考虑,它的现存的分配计算会变成新队列的资源分配。如果加入被移动的应用程序的资源超出目标队列的maxRunningApps 或者maxResources 限制,本次移动将会失败。