本文翻译自 http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html
和http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html
1、目的
本文主要描述容量调度器,它是一个可拔插的插件,负责为所有的应用按照特定的限制分配资源。
2、概览
cs(译注:为了便于写,把CapacitiesScheduler编写为cs)的目的就是能够让hadoop应用以操作员友好的方式运行,并能够最大化集群的吞吐和利用。
以往,每个组织都有自己私有的计算资源,并且这些资源具有足够的容量来满足不同时段组织的SLA。这通常会导致交叉的平均利用,并会让管理有点不堪重负,因为如果组织多的话,那么集群也会很多。在不同组织之间共享hadoop集群是比较划算的行为,因为不需要创建私有的集群。然后,每个组织都会关心共享的事情,因为大家都担忧其他组织过分使用集群资源。
cs能够让应用共享集群,并保证应用的资源需求(译注:保证各个应用预先分配的资源,例如不会用着用着,然后发生cpu都被其它应用霸占了之类的事情.并不是说能够让每个应用都可以畅快地使用所有的资源)。中心思想就是共享。此外还有一个不一样的好处,某个时刻某个组织可以使用其它其它组织的资源--换言之,组织可以弹性利用资源。
cs提供一系列严格的限制来确保单个的应用/用户/队列无法消费过量的资源。此外,cs对用户或者队列的初始/挂起应用做某种限制,这样可以确保集群的公平和稳定。
cs的首要概念是队列(queues).这些队列由管理员设置,队列可以实现共享集群的共享经济。
为了提供对资源的进一步的控制,和共享的可预见性,cs支持分层队列(译注:原文hierarchical ),确保在其它队列可以利用空闲资源之前,特定组织的队列(包括子队列)可以共享资源,由此特定组织的的应用可以更好地共享空闲资源。
译注:
- sla,这里并非指hadoop的服务级别授权,而是指“服务级别协议”,具体可以参考http://www.sohu.com/a/111043704_120672 ,但可以简单理解为“需求”
- 这个小节的中心思想就是:cs,共享,队列,分层队列,确保
3、特性
- Hierarchical Queues - 分层队列。确保在其它队列可以利用空闲资源之前,特定组织的队列(包括子队列)可以共享资源,由此特定组织的的应用可以更好地共享空闲资源
- Capacity Guarantees -容量保证。系统分配给队列分配容量的一部分,这部分就归特定队列处置。队列中的应用都可以访问分配给队列的容量。管理员可以为队列配置软限制和可选的硬限制
- Security -安全。每个队列都有严格的ACLs,acls控制谁可以提交应用到队列中。此外,一个用户不能看/修改其它用户队列的应用。
- Elasticity - 弹性。任何队列可以利用空闲资源,即使已经超过了自身的限额。
- Multi-tenancy - 多租户。有各种设置来保证资源不会被独占,大家可以共享。
- Operability --可操作
- 运行时配置 - 队列定义和属性(如容量),ACLS可以在运行时由管理员以安全的方式修改。此外为管理员和用户提供了一个控制台,通过控制台可以查看当前资源的分配。管理员可以在运行时添加队列,但不能删除正在运行的队列。(译注:如果这样,只能先停止应用了或者先停止队列)
- 释放应用- 管理员可以在运行时stop队列,但正在运行得应用可以一致运行到完成,而新的应用不能加入队列。如果队列处于STOPPED状态,那么就无法添加新应用到队列或者子队列上。这样管理员可以优雅地停止队列. 此外,管理员可以启动正在停止中(STOPPED)的队列.
- Resource-based Scheduling(基于资源的调度) - 支持资源密集应用(译注:简而言之就是可以不同需求给予不同资源). 目前支持的资源只有内存。
- Queue Mapping based on User or Group - 基于用户/组的队列映射 。换言之,不同的用户或者组所提到的作业会对应到不同队列,适当程度简化了操作。
- Priority Scheduling 优先权调度- 不同应用可以按照不同的优先权调度。应用的优先权值越大,优先级越高。目前,应用优先权只支持FIFO策略。译注:应该指的是在先按照优先权排序的情况下,最大优先权的的可以进入FIFO堆栈,但绝对不能插队。
4、配置
4.0 使用容量调度器
修改yarn-site.xml
yarn.resourcemanager.scheduler.class 取值 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
4.1 配置队列
etc/hadoop/capacity-scheduler.xml
cs有个预定义的队列root。所有的队列都是这个队列的子队列。
其它队列可以通过yarn.scheduler.capacity.root.queues配置,多个队列以逗号分隔。
使用队列路径来设定队列的层级。队列路径必须是全路径,以root开始,使用点号作为分隔符。
特定的子队列可以使用以下形式定义yarn.scheduler.capacity.<queue-path>.queues。子队列并不继承上级队列的属性,除非有特别说明。
以下是一个例子,有3个顶级子队列a,b,c。a,b有一些子队列:
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>a,b,c</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.b.queues</name>
<value>b1,b2,b3</value>
<description>The queues at the this level (root is the root queue).
</description>
</property>
4.2 队列属性
- 资源分配
属性 | 描述 |
---|---|
yarn.scheduler.capacity.<queue-path>.capacity |
容量百分比,可以有小数位。但所有队列的和必须是100。但如果系统有空闲资源,队列中的应用实际是可能耗费比限定的份儿跟多的资源,这就是弹性。 |
yarn.scheduler.capacity.<queue-path>.maximum-capacity |
队列允许使用的最大份额百分比。默认-1,就是不允许。 |
yarn.scheduler.capacity.<queue-path>.minimum-user-limit-percent |
队列中用户的资源下限(百分比-但必须是整数)。用户实际使用的资源可能介于两个限制点之间。一个队列可能包含了多个用户的应用,那么如果一个队列有2个提交了应用的用户, 那么可以限制50,3个就是33,3个就是25,诸如此类。如果设置为100(默认),那么就是不做限制,这样占先用。 |
yarn.scheduler.capacity.<queue-path>.user-limit-factor |
定义某个用户可以使用的容量倍数。默认是1,就是队列容量的全部。这个值可以带小数。 译注:这应该是一个<=1的值。 |
yarn.scheduler.capacity.<queue-path>.maximum-allocation-mb |
资源可以管理器分配给容器的最大内存(分配对队列的最大内存)。这个设置会覆盖 yarn.scheduler.maximum-allocation-mb。但必须小于等于集群的最大限额。 |
yarn.scheduler.capacity.<queue-path>.maximum-allocation-vcores |
最大的虚拟核(virtual core).覆盖 yarn.scheduler.maximum-allocation-vcores,但必须小于等于后者。 |
- 运行和挂起应用
Property | Description |
---|---|
yarn.scheduler.capacity.maximum-applications yarn.scheduler.capacity.<queue-path>.maximum-applications |
系统并发的正在运行和挂起的应用总数,默认是10000. yarn.scheduler.capacity.<queue-path>.maximum-applications可以覆盖 yarn.scheduler.capacity.maximum-applications的值,但值只能小于等于后者。 取值为整数。 |
yarn.scheduler.capacity.maximum-am-resource-percent yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent |
am可以使用的最大资源百分比(用于并发的活动应用)。取值为浮点数,例如0.5,表示50%。 yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent可以覆盖 yarn.scheduler.capacity.maximum-am-resource-percent,但取值必须小于等于后者。 |
译注:每一行,有两个属性
- 队列管理和权限
Property | Description |
---|---|
yarn.scheduler.capacity.<queue-path>.state |
设置队列的状态,可以是RUNNING/STOPPED.如果是后者,则队列不能增加新应用,但现有运行得应用可以一致运行到结束。 |
yarn.scheduler.capacity.root.<queue-path>.acl_submit_applications |
队列提交应用权限列表acl--控制谁可以提交应用。如果用户/组有队列(或者升级队里的)acl权限,那么就可以提交应用。 如果没有设定,那么从其上级继承。 |
yarn.scheduler.capacity.root.<queue-path>.acl_administer_queue |
控制谁可以管理队列的应用。 其它方式同上一行属性。 译注:原文没有说如何管理。停止,删除? |
注:这个acl的格式不同于hdfs文件的acl格式。*表示任何人,space表示没有人。对于root队列来说,如果没有设定,默认是*
- 基于用户/组的队列隐射
Property | Description |
---|---|
yarn.scheduler.capacity.queue-mappings |
语法 [u or g]:[name]:[queue_name][,next_mapping]* 列表可以多个,之间以逗号分隔。 %user放在[name]部分,表示已经提交应用的用户。 如果队列名称和用户一样,那可以使用%user表示队列。 如果队列名称和用户主组一样,可以使用%primary_group表示队列。 译注:这个语法有点怪异 |
yarn.scheduler.capacity.queue-mappings-override.enable |
定义针对特定用户的队列是否可以被覆盖。默认是false. 译注:没有说明如何覆盖 |
例子:
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user1:queue1,g:group1:queue2,u:%user:%user,u:user2:%primary_group</value>
<description>
Here, <user1> is mapped to <queue1>, <group1> is mapped to <queue2>,
maps users to queues with the same name as user, <user2> is mapped
to queue name same as <primary group> respectively. The mappings will be
evaluated from left to right, and the first valid mapping will be used.
u:%user:%user ---已经提交应用的用户,映射到和用户名称一样的队列上。
u:user2:%primary_group --user2提交的应用映射到user2主组名称一样的队列上。
</description>
</property>
译注:如果用户组并不多,队列也不多,建议还是使用简单的语法,而不要使用带%的,后者有点混,而且还不知道是否会导致异常。
4.3 配置应用优先权
应用优先和FIFO排序策略一起工作。
Default priority for an application can be at cluster level and queue level.
应用的默认优先权可以设定集群或者队列级别。
- 集群级别 : 定义了整个集群的最大优先权(整数值),具体原因的优先全如果大于它,那么就以集群最大优先权为准。. $HADOOP_HOME/etc/hadoop/yarn-site.xml 配置了这个值.
Property | Description |
---|---|
yarn.cluster.max-application-priority | Defines maximum application priority in a cluster. |
- 叶子队列级别 : $HADOOP_HOME/etc/hadoop/capacity-scheduler.xml 可以配置这个叶子级别的。
Property | Description |
---|---|
yarn.scheduler.capacity.root.<leaf-queue-path>.default-application-priority | Defines default application priority in a leaf queue. |
注意: 如果应用移动到不同的队列,其优先权不会改变
4.4 容量调度容器抢占
cs支持容器抢占,就是如果有一些队列使用了超限的资源,那么这些超限的资源是可以被抢走的。
- yarn-site.xml 的配置
Property | Description |
---|---|
yarn.resourcemanager.scheduler.monitor.enable |
启用监视程序。默认不启用 译注:应该设置为true |
yarn.resourcemanager.scheduler.monitor.policies |
监视策略 默认值是 org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy |
如果yarn.resourcemanager.scheduler.monitor.policies的取值是org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy
- 那么可以配置一下属性(同样是在yarn-site.xml中)
Property | Description |
---|---|
yarn.resourcemanager.monitor.capacity.preemption.observe_only |
眼观手不动-不抢也不杀事件。默认是false. 译注:应该设置为true |
yarn.resourcemanager.monitor.capacity.preemption.monitoring_interval |
监视间隔(轮询/扫描间隔),默认是3000毫秒。 |
yarn.resourcemanager.monitor.capacity.preemption.max_wait_before_kill |
从发出抢占请求到杀掉容器的时间,默认是15000毫秒 |
yarn.resourcemanager.monitor.capacity.preemption.total_preemption_per_round |
一个回合中,抢占的最大的资源百分比。通过控制这个值,就可以限制从集群申请容器的步伐。 在计算总的期望抢占(需求)后,策略会要求总和必须小于=这个值。默认是0.1 译注:这个比率必须乘以100,才是百分比。 |
yarn.resourcemanager.monitor.capacity.preemption.max_ignored_over_capacity |
如果无法抢占那么多,那么可以少抢多少? 这个值积极的一面是可以防止可能无法抢到。 如果这个值比较高,那么可能无法那么快抢到需要的容量。默认是0.1 |
yarn.resourcemanager.monitor.capacity.preemption.natural_termination_factor |
自然终止抢占百分比(差额). 对于一个计算过的抢占, 由于容器自然过期,那么就只会抢占这个比率的差额。 这个确定了几何比率(这个比率和MAX_IGNORED_OVER_CAPACITY有关)。 李I如,如果因子是0.5(就是5%),那么差额就是95%. 那么在 5 * #WAIT_TIME_BEFORE_KILL间隔内,就会申请几乎95%的资源,即使没有自然终止(其它的应用或者容器)。 默认值是0.2(2%)。 译注:这个定义挺奇怪的。 |
- capacity-scheduler.xml 中关于已经属于队列的应用容器抢占配置 。
Property | Description |
---|---|
yarn.scheduler.capacity.<queue-path>.disable_preemption |
是否禁止抢占已经属于队列的应用容器。 仅当以下两个属性设置如下的时候,本属性才启用: yarn.resourcemanager.scheduler.monitor.enable = true yarn.resourcemanager.scheduler.monitor.policies = org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy 如果特定队列没有设定,就从上级队列继承。 默认是false(译注:就是可以抢) |
- 保留管理
cs可以通过参数来控制创建,删除,更新和列出预留信息。注意,任何人都可以这么做,只要有权限(自己的可以操纵自己的)。如果有启用预留acl,但又没有定义,那么任何人都可以操作。
在下面这个例子中,<queue>是队列名称。
Property | Description |
---|---|
yarn.scheduler.capacity.root.default.acl_administer_reservations | 设置默认队列的管理acl |
yarn.scheduler.capacity.root.<queue>.acl_administer_reservations |
这个ACL具有全部权限:创建,删除,修改和列出。 这个权限不继承上级的,除非有特定说明(译注:如何特别说明) 译注:文档并没有给出acl的示例。但根据本文多次出现过的经验来看,也许是“u:user1:queue1,g:group1:queue2”这样形式的。 |
yarn.scheduler.capacity.root.<queue>.acl_list_reservations |
查看权限。 这个权限不继承上级的,除非有特定说明(译注:如何特别说明) |
yarn.scheduler.capacity.root.<queue>.acl_submit_reservations |
提交(创建) 这个权限不继承上级的,除非有特定说明(译注:如何特别说明) |
译注:上表的属性中包含了<queue>而不是<queue-path>,当时原文作者的疏忽所致。本人认为,这应该修改为<queue-path>更好,更容易理解,也可以保持全文一致。
4.5 使用容量调度器配置预订系统
cs支持预订系统-允许用户预留资源。
应用可以在运行时(提交)设定 reservationId,以请求保留的资源。
- yarn-site.xml 中的配置
Property | Description |
---|---|
yarn.resourcemanager.reservation-system.enable |
是否启用预订(非空) 默认为否(false) 取值true/false |
yarn.resourcemanager.reservation-system.class |
预订类(可选) 如果没有设置,就直接取 yarn-site.xml中yarn.resourcemanager.scheduler.class属性值。 译注:cs的话,就取 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler |
yarn.resourcemanager.reservation-system.plan.follower |
PlanFollower类名,用于定时同步cs(可选参数) 取值和yarn.resourcemanager.scheduler.class属性值有关。 如果cs,那么取值org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacitySchedulerPlanFollower |
yarn.resourcemanager.reservation-system.planfollower.time-step |
PlanFollower定时器的间隔(毫秒-整数,可选参数)。 默认是1000毫秒 |
- capacity-scheduler.xml中的配置
cs支持预订,而且可以在任意叶子队列上配置。
Property | Description |
---|---|
yarn.scheduler.capacity.<queue-path>.reservable |
是否可以预订(非空) 默认false(不可以) 译注:因为设置就是为了预订,所以一般设定为true |
yarn.scheduler.capacity.<queue-path>.reservation-agent |
预订代理(类名),用于确定预订代理是否已经实现。 默认值:org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.AlignedPlannerWithGreedy. |
yarn.scheduler.capacity.<queue-path>.reservation-move-on-expiry |
可选参数 当有关的预订过期后,应用是否要移动到上级可预订的队列(或者是被杀掉) 默认是true. |
yarn.scheduler.capacity.<queue-path>.show-reservations-as-queues |
可选参数 是否在调度器UI中显示预订队列。 默认false(不显示) |
yarn.scheduler.capacity.<queue-path>.reservation-policy |
预订策略类(可选参数) 用于确定共享策略是否实现了,这个共享策略负责验证新的预订没有破坏标准。 默认值是org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacityOverTimePolicy. |
yarn.scheduler.capacity.<queue-path>.reservation-window |
预留窗口(可选参数) 单位毫秒(必须是整数) 共享策略类在这个窗口内会验证计划中约束是否通过。 默认是1天(86400000) |
yarn.scheduler.capacity.<queue-path>.instantaneous-max-capacity |
瞬间最大容量(可选参数) 实际是任意时间,单位是比率(但不是百分比) 共享策略允许单个用户保留的最大容量 默认是1,也就是100%. |
yarn.scheduler.capacity.<queue-path>.average-capacity |
平均容量(可选参数) 在预订窗口内,共享策略允许单个用户保留的平均容量。 默认是1(100%) |
yarn.scheduler.capacity.<queue-path>.reservation-planner |
预订计划执行程序(类,可选) 用于确认计划程序的实现情况,如果计划容量低于用于预订的,那么这个类会被激活。 默认值 org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.SimpleCapacityReplanner 这个类被激活后,会扫描计划,并按照LIFO的顺序尽可能地移除预留的容量,直到预留的资源达到了计划要求。 译注:LIFO--即后进先出。 |
yarn.scheduler.capacity.<queue-path>.reservation-enforcement-window |
预留强制窗口(可选) 计划程序在这个时间窗口内,会验证计划限定是否被满足了。 整数类型,单位毫秒 默认是1小时即3600000 |
译注:具体如何预订,并不是仅仅这几个参数。实际实现的时候,还需要结合一些其它操作,例如yarn关于rm的REST API
也许以后,yarn自己会提供cli工具直接申请预订并提交作业,目前来看,需要通过编程来实现。
但很多时候,如果不直接使用yarn的话,也不需要考虑这个,例如使用spark,presto的时候,它们可以和yarn一起部署。
预订系统更多的内容可以参阅http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html
4.6 其它属性
- 资源计算器
Property | Description |
---|---|
yarn.scheduler.capacity.resource-calculator |
资源计算器类-比较调度器中的资源。 例如org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator仅仅计算内存,而DominantResourceCalculator会使用内存,cpu等等。 译注:目前还是使用 org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator 吧。 因为有关的实现主要基于内存的。 yarn的资源管理还是比较初级的。 |
- 数据本地性
Property | Description |
---|---|
yarn.scheduler.capacity.node-locality-delay |
节点局部性延迟 在cs企图调度本地机栈容器后(失败),还可以错过错过多少次的调度次数。 通常设置为集群节点数。 默认情况下,应该设置为基站中节点数,例如40(一个机栈可能有40台)。 译注:调度器在本地机栈找资源,可以在机栈内的节点一个个找过去。所以可以尝试那么多次。 由于没有看有关的代码,并不清楚具体如何一个个找的。 |
4.7 回顾容量调度器配置
一旦按照配置完毕,这些配置可以通过yarn的WEB-UI来查看:
- 以常规模式启动yarn
- 打开rm的web-ui
- 找到 /scheduler 页面,就可以看到队列和有关资源.
5、修改队列配置
修改队列属性,添加队列是非常简单。只需要编辑conf/capacity-scheduler.xml,并执行 yarn rmadmin -refreshQueues
$ vi $HADOOP_CONF_DIR/capacity-scheduler.xml
$ $HADOOP_YARN_HOME/bin/yarn rmadmin -refreshQueues
注意: 队列不能删除,但可以添加新的,更新也是可以的。
译注:不需要修改所有节点上的,因为rmadmin会自动做那个事情。此外如何删除队列?难道要靠重配,重启yarn集群吗?
以下内容翻译自 http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html
6、预订系统
译注:本文已经省略掉一些原文的内容
流程图
典型预订流程:
- Step 0 用户提交一个预订创建请求,并接收到一个响应,响应包含一个ReservationId(预订ID)
- Step 1 用户提交一个预订请求(使用 Reservation Definition Language (RDL) --预定定义语言)和预订ID,请求包括诸如资源和暂时约束(例如截止时间)。这个提交可以使用编程方式完成,编程方式包括使用客户端到RM的协议或者RM REST api 。如果相同的RDL内容和预订ID提交做了多次,但是是无用的,系统不会创建新的预留,虽然系统的提示是成功的。如果仅仅RDL不同,那么会被拒绝。
- Step 2 预订系统启动一个预订代理(ReservationAgent,上图绿色的。译注:原文说绿色,但本文看到的是蓝色的),从PLAN(计划中)找一可用的分配,所谓PLAN(计划)就是一个数据结构,记录了所有已经接收的预订和系统中的可用资源。
- Step 3 共享策略提供一个途径来强制收到的预留是恒定的(至少是符合要求的),而这个收到的可能是潜在会被拒绝的。 例如,CapacityOvertimePolicy会允许用户的瞬时最大容量,但一段时间内又会做一定的限制 。例如用户的瞬时请求可以是50%的集群容量,但在24小时内,均值不能超过10% 。
- Step 4 成功验证后,预订系统会返回给用户一个预订ID(可以比作一张车票)
- Step 5 当预订时间到达,部件PlanFollower(后续计划程序)把计划的状态推送给调度器 ,推送方式是动态创建/ 调整/销毁队列。
- Step 6 然后用户可以提交一个或者多个作业给预留队列,提交的时候只需要简单地包含预订ID即可。
- Step 7 调度器会提供一些容器(这些容器已经预先创建,用于满足预订需求)。在预订限制内,用户可以随意使用资源。
- Step 8 系统包含适应/脱离集群容量的机制。包括如果可能就移动预留,或者拒绝一些最小量的请求
译注:总体上预订的实现分为几个步骤:
1.预订
2.执行,包含提交计划和调整共享。
3.脱离(完结)