YARN 中包含 3 种可用的调度起:FIFOScheduler(先入先出调度器)、CapacityScheduler(容量调度器)、 FairScheduler(公平调度器)。
本文主要介绍 CapacityScheduler(容量调度器)相关的配置。
1. CapacityScheduler 概述
CapacityScheduler(容量调度器)是一个用于 Hadoop 的可插拔调度器,它允许多个租户安全地共享大型 YARN 集群,以便用户的应用程序可以在分配容量的约束下及时分配资源。
CapacityScheduler 旨在以用户友好的方式将 Hadoop 应用程序运行在多租户共享的 YARN 集群中,同时最大限度地提高 YARN 集群的吞吐量和利用率。
CapacityScheduler 旨在允许共享大型集群,同时为每个组织提供容量保证。CapacityScheduler 提供了一组严格的限制,以确保单个应用程序、用户或队列不会消耗集群中不成比例的资源量。此外,CapacityScheduler 对单个用户和队列中已初始化和待处理的应用程序提供限制,以确保集群的公平性和稳定性。
CapacityScheduler 提供了队列的概念。为了提供对资源共享的进一步控制和可预测性,CapacityScheduler 支持分层队列,以确保在允许其他队列使用空闲资源之前,先在组织的子队列之间共享资源,从而提供在组织的应用程序之间共享空闲资源的亲和力。
2. CapacityScheduler 特性
CapacityScheduler(容量调度器)具有如下特性:
分层队列- 支持队列分层结构,以确保在允许其他队列使用空闲资源之前,先在组织的子队列之间共享资源,从而提供更多的控制和可预测性。容量保证- 意味着每个队列都被分配了一定比例的资源容量。每个队列获得的资源容量是固定的,所有提交到队列的应用程序都可以使用这些资源。管理员可以对分配给每个队列的容量配置软限制和可选的硬限制。安全性- 每个队列都有严格的 ACL,控制哪些用户可以向队列提交应用程序。此外,还有一些安全措施可确保用户无法查看和/或修改其他用户的应用程序。此外,每个队列还支持系统管理员角色。弹性- 可以将空闲资源分配给超出其容量的任何其他队列。当未来某个时间点运行低于容量的队列需要这些资源时,随着在这些资源上调度的任务完成,空闲的资源将被分配给运行低于容量的队列上的应用程序(也支持抢占)。这确保了资源以可预测和弹性的方式提供给队列,从而防止集群中的人为资源孤岛,从而有助于提高利用率。多租户- 提供全面的限制,以防止单个应用程序、用户和队列独占队列或整个集群的资源。操作性运行时配置- 管理员可以在运行时以安全的方式更改队列定义和属性(例如容量、ACL),以最大程度地减少对用户的干扰。此外,还为用户和管理员提供了一个控制台,用于查看系统中各个队列的当前资源分配情况。管理员可以在运行时添加其他队列,但不能在运行时删除队列,除非队列已停止且没有待处理/正在运行的应用程序。排出应用程序- 管理员可以在运行时停止队列,以确保现有应用程序运行完成时,不能提交新的应用程序。如果队列处于 STOPPED 状态,则无法将新应用程序提交给其自身或其任何子队列。现有应用程序可以继续执行,因此队列可以正常排出。管理员还可以启动已停止的队列。
基于资源的调度- 支持资源密集型应用程序,其中应用程序可以选择指定比默认值更高的资源需求,从而适应具有不同资源要求的应用程序。目前,内存是支持的资源需求。基于默认或用户定义的放置规则的队列映射接口- 此功能允许用户根据某些默认放置规则,将作业映射到特定队列。例如基于用户和组或应用程序名称。用户还可以定义自己的放置规则。优先级调度- 此功能允许以不同的优先级提交和调度应用程序。整数值越高表示优先级越高。目前,仅 FIFO 排序策略支持应用程序优先级。绝对资源配置- 管理员可以为队列指定绝对资源,而不是提供基于百分比的值。这为管理员提供了更好的控制,以便为给定队列配置所需的资源量。子队列的动态自动创建和管理- 此功能支持与队列映射结合自动创建子队列,队列映射当前支持基于用户组的队列映射,以将应用程序放置到队列。Scheduler还支持根据父队列上配置的策略对这些自动创建的子队列进行容量管理。
3. CapacityScheduler 配置
3.1. 设置 ResourceManager 以使用 CapacityScheduler
要将 ResourceManager 配置为使用 CapacityScheduler,请在 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中设置以下属性:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
3.2. 设置队列
$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml 是 CapacityScheduler 的配置文件。其中,预定义了一个名为 root 的队列,系统中的所有队列都是 root 队列的子队列。
可以通过使用逗号(,)分隔的子队列列表配置 yarn.scheduler.capacity.root.queues 来设置更多队列。CapacityScheduler 使用称为 队列路径 的概念来配置队列的层次结构。队列路径 是队列层次结构的完整路径,从 root 开始,以点(.)作为层次分隔符。
要创建给定队列的子队列,可以使用配置属性 yarn.scheduler.capacity.<queue-path>.queues 来定义。这里的 <queue-path> 指的是队列的路径,用于唯一标识特定队列及其位置。除非另有说明,子队列不会直接从父队列继承属性。
如下是一个包含 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>
上述 CapacityScheduler 队列的配置示例所定义的队列层次结构,如下所示。
root ├── a │ ├── a1 │ └── a2 ├── b │ ├── b1 │ ├── b2 │ └── b3 └── c
3.3. 队列属性
- 资源容量限制
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.<queue-path>.capacity |
队列容量,以浮点形式(如 12.5)的百分比(%)表示或以队列最小容量的绝对资源量表示。每个层级的所有队列的容量总和必须等于 100。但是,如果配置了绝对资源,则子队列的绝对资源总和可能小于其父队列的绝对资源容量。 如果有空闲资源,队列中的应用程序可能会消耗比队列容量更多的资源,从而提供弹性。 |
yarn.scheduler.capacity.<queue-path>.maximum-capacity |
队列最大容量,以浮点形式的百分比(%)表示或以队列最大容量的绝对资源量表示。这限制了队列中应用程序的弹性。1) 值介于 0 和 100 之间。 2) 管理员需要确保每个队列的 绝对最大容量 >= 绝对容量。此外,将此值设置为 -1 会将最大容量设置为 100%。 |
yarn.scheduler.capacity.<queue-path>.minimum-user-limit-percent |
若存在资源需求,每个队列都会强制限制分配给用户的资源百分比。此百分比可以介于最小值与最大值之间。 最小值由属性 yarn.scheduler.capacity.<queue-path>.minimum-user-limit-percent 设定(应为整数),而最大值则取决于提交应用程序的用户数量。例如,假设此属性值为 25。若 2 个用户向队列提交了应用程序,则任何单个用户都不能使用超过 50% 的队列资源。若第3个用户提交了应用程序,则任何单个用户都不能使用超过 33% 的队列资源。对于 4 个用户,任何用户都不能使用超过 25% 的队列资源。默认值为 100,表示不对用户施加任何限制。 |
yarn.scheduler.capacity.<queue-path>.user-limit-factor |
允许单个用户获取的队列容量的倍数(浮点数),此配置可允许单个用户获取更多资源。 默认值为 1,可确保单个用户永远不会占用超过队列配置的容量,无论集群有多空闲。当值大于1时,可允许单个用户获取超过队列配置的容量限制的资源。 |
yarn.scheduler.capacity.<queue-path>.maximum-allocation-mb |
向 ResourceManager 请求分配给队列中容器内存资源时的最大值,该值必须 ≤ 集群总内存最大值。此设置会覆盖集群配置 yarn.scheduler.maximum-allocation-mb。 |
yarn.scheduler.capacity.<queue-path>.maximum-allocation-vcores |
向 ResourceManager 请求分配给队列中容器 CPU vcore 资源时的最大值,该值必须 ≤ 集群CPU核心数最大值。此设置会覆盖集群配置 yarn.scheduler.maximum-allocation-vcores。 |
yarn.scheduler.capacity.<queue-path>.user-settings.<user-name>.weight |
此浮点值用于计算队列中各个用户的用户限制资源,该权重值将使某个用户的资源限制权重高于或低于队列中其他用户的权重。 例如,若用户 A 在队列中需要的资源比用户 B 和 C 多 50%,则用户 A 的该属性值应设置为 1.5,而用户 B 和 C 将默认设置为 1.0。 |
- 用绝对资源进行资源容量限制
CapacityScheduler 支持用绝对资源量来限制队列的资源容量。正如前文提到的 yarn.scheduler.capacity.<queue-path>.capacity 和 yarn.scheduler.capacity.<queue-path>.max-capacity,管理员可以指定一个绝对资源数值,如[memory=10240,vcores=12],表示将资源容量为 10GB 内存 和 12 个 VCore。
- 正在运行和待处理的应用程序数量限制
CapacityScheduler 支持以下参数来控制正在运行和待处理的应用程序:
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.maximum-applicationsyarn.scheduler.capacity.<queue-path>.maximum-applications |
系统中可以同时处于活动状态(正在运行和待处理)的应用程序的最大数量(整数值),默认为 10000。每个队列的限制与其队列容量和用户限制成正比。 这是一个硬性限制,达到此限制时提交的任何应用程序都将被拒绝。 可以用 yarn.scheduler.capacity.maximum-applications 为所有队列设置此限制,也可以用 yarn.scheduler.capacity.<queue-path>.maximum-applications 为特定的队列进一步限制。 |
yarn.scheduler.capacity.maximum-am-resource-percentyarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent |
集群中可用于运行应用程序主机的最大资源百分比(浮点值,默认值 0.1 表示10%),可控制并发活动应用程序的数量。每个队列的限制与其队列容量和用户限制成正比。可以用 yarn.scheduler.capacity.maximum-am-resource-percent 为所有队列设置此限制,也可以用 yarn.scheduler.capacity.<queue-path>.maximum-am-resource 为特定的队列进一步限制。 |
yarn.scheduler.capacity.max-parallel-appsyarn.scheduler.capacity.<queue-path>.max-parallel-apps |
可以同时运行的应用程序的最大数量(整数值,默认无限制)。与 maximum-applications 不同,达到此限制时不会拒绝提交的申请,而是一直处于 ACCEPTED 状态,直到有资格运行为止。可以用 yarn.scheduler.capacity.max-parallel-apps 为所有队列设置此属性,也可以用 yarn.scheduler.capacity.<queue-path>.max-parallel-apps 为特定的队列进一步限制。最大并行应用程序限制是队列层次结构中的继承属性,这意味着将选择最小值作为层次结构的每个队列中的强制限制。 |
还可以限制每个用户的并行应用程序数量。
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.user.max-parallel-apps |
所有用户可以同时运行的应用程序的最大数量,默认无限制。 |
yarn.scheduler.capacity.user.<username>.max-parallel-apps |
特定用户可以同时运行的最大应用程序数,此属性会覆盖全局设置。 |
这些资源限制的评估按以下顺序进行:
-maximum-applications检查 - 如果超出限制,作业提交将立即被拒绝。
-max-parallel-apps检查 - 提交被接受,但应用程序不会转换为RUNNING状态,而是保持在ACCEPTED状态,直到满足队列/用户的资源限制。
-maximum-am-resource-percent检查 - 如果正在运行的Application Masters太多,应用程序将保持在ACCEPTED状态,直到有足够的空间。
- 队列管理和权限
CapacityScheduler 支持以下属性来管理队列:
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.<queue-path>.state |
队列的状态,是一个枚举值,可以是 RUNNING 或 STOPPED。若队列处于 STOPPED 状态,则无法向该队列或其子队列提交新应用程序。因此,若 root 队列 STOPPED,则无法向 YARN 集群提交任何应用程序。停止队列吼,队列中现有的应用程序会继续执行,因此队列可以正常排出。 |
yarn.scheduler.capacity.root.<queue-path>.acl_submit_applications |
ACL 控制谁可以向给定队列提交应用程序。 若给定用户/组在给定队列或层次结构中的父队列之一上具有必要的 ACL,则他们可以提交应用程序。 若未指定,此属性的 ACL 将从父队列中继承。 若在此列表中的用户名前面添加波浪号 ( ~),则真实用户的 ACL 将允许代理用户向队列提交应用程序。 |
yarn.scheduler.capacity.root.<queue-path>.acl_administer_queue |
ACL 控制谁可以管理给定队列上的应用程序。 若给定用户/组在给定队列或层次结构中的父队列之一上具有必要的 ACL,则他们可以管理队列中的应用程序。 若未指定,此属性的 ACL 将从父队列中继承。 若此列表中的用户名前面添加波浪号 (~),则真实用户的 ACL 将允许代理用户管理队列中的应用程序。 |
【注意】
ACL的格式为用户之间或用户组之间用逗号(,)分割,而用户与用户组之间用空格分割,例如user1,user2 group1,group2。 特殊值*表示所有人。若未指定ACL属性,root队列的默认值为*。
- 基于用户或组、应用程序名称或用户定义的放置规则的队列映射
CapacityScheduler 支持用如下属性配置基于 用户或组、用户与组、应用程序名称 的队列映射。用户还可以定义自己的放置规则:
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.queue-mappings |
此属性指定了用户或组到特定队列的映射关系。 可以将单个用户或一组用户映射到队列,语法为 [u或g]:[name]:[queue_name][,next_mapping]*:其中的 u 或 g 表示映射是针对用户还是组,u 表示用户,g 表示组。name 表示用户名或组名,可以用 %user 来指定提交应用程序的用户。queue_name 表示要映射到的队列名,可以用 %user 来指定队列名与用户名相同;可以用 %primary_group 来指定队列名与用户的主要组名相同;可以用 %secondary_group 来引用用户的次要组。 |
yarn.scheduler.queue-placement-rules.app-name |
此属性指定了应用程序 app_name 到特定队列的映射关系。可以将单个应用程序或应用程序列表映射到队列,语法为 [app_name]:[queue_name][,next_mapping]*:其中的 app_name 表示要进行映射的应用程序名称,queue_name 指示应用程序必须映射到的队列名。可以用 %application 将当前的应用程序名称指定为 app_name。 |
yarn.scheduler.capacity.queue-mappings-override.enable |
此属性用于指定是否可以覆盖用户指定的队列(布尔值),默认为 false。 |
下面的示例分别涵盖了单个映射。若存在使用逗号分隔值的多个映射,则将从左到右进行评估求解,并且将使用第一个有效映射。下面的示例顺序是根据多个映射情况下运行时的实际执行顺序记录的。
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:%user:%primary_group.%user</value>
<description>将用户映射到与用户名相同的队列,但父队列的名称应与用户的主要组相同。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:%user:%secondary_group.%user</value>
<description>将用户映射到与用户名相同的队列,但父队列的名称应与用户的任意次要组相同。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:%user:%user</value>
<description>将用户映射到与用户名相同的队列。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user2:%primary_group</value>
<description>将用户 user2 映射到与该用户主要用户组同名的队列。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user3:%secondary_group</value>
<description>将用户 user3 映射到与该用户任意次要用户组同名的队列。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user1:queue1</value>
<description>将用户 user1 映射到队列 queue1。</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>g:group1:queue2</value>
<description>将用户组 group1 映射到队列 queue2</description>
</property>
...
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user1:queue1,u:user2:queue2</value>
<description>将用户 user1 映射到队列 queue1,将用户 user2 映射到队列queue2。</description>
</property>
<property>
<name>yarn.scheduler.queue-placement-rules.app-name</name>
<value>appName1:queue1,%application:%application</value>
<description>
将应用程序 appName1 映射到队列 queue1,将当前应用映射到与应用名称同名的队列。此映射将被从左至右进行求解,并且将使用第一个有效映射。</description>
</property>
- 应用程序的队列生命周期
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.<queue-path>.maximum-application-lifetime |
此属性指定了提交到队列的应用程序的最大生存期(单位为秒)。任何 ≤0 的值都被视为禁用(即无限制),而默认值为 -1。若设为正值,则提交到该队列的应用程序将在超过配置的生存期后被终止(kill)。用户还可以在应用程序提交上下文中指定每个应用程序的生命周期。但是,如果用户生命周期超过队列最大生命周期,则用户生命周期将被队列中的值覆盖。 注意:此属性可以在队列层次结构中的任何级别设置。子队列若未设置此属性(或设置为负值),将继承其父队列的值;子队列若设置了正值,则将覆盖父队列的值。 0 表示没有最大生命周期,并将覆盖父级的最大生命周期。 |
yarn.scheduler.capacity.root.<queue-path>.default-application-lifetime |
此属性指定了提交到队列的应用程序的默认生存期(单位为秒),这是一种即时的配置。此属性值不能超过最大生存期设置。任何 ≤0 的值都被视为禁用(即无限制)。若用户未指定应用程序的生存期,则会采用这个默认值。此属性可以在队列层次结构的任何级别进行设置。子队列会继承父队列的值,除非在子队列级别进行了覆盖。 |
3.4. 设置应用程序优先级
应用程序优先级仅与 FIFO 排序策略一起使用,CapacityScheduler 的默认排序策略就是 FIFO。应用程序的默认优先级可以是 集群级别 和 队列级别:
- 集群级别优先级
任何优先级高于集群最大优先级的应用程序,在向YARN集群提交时都会将其优先级重置为集群最大优先级。$HADOOP_HOME/etc/hadoop/yarn-site.xml是集群最大优先级的配置文件。
| 属性(Property) | 描述 |
|---|---|
yarn.cluster.max-application-priority |
定义 YARN 集群中的最大应用程序优先级。 |
- 子队列级别优先级
每个子队列由管理员提供默认优先级。队列的默认优先级将应用于在执行提交时未指定优先级的应用程序。$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml是队列级别优先级的配置文件。
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.root.<leaf-queue-path>.default-application-priority |
定义子队列中的默认应用程序优先级。 |
【注意】
当将应用程序移动到不同的队列时,应用程序的优先级不会改变。
3.5. CapacityScheduler 容器抢占
CapacityScheduler 支持从资源使用量超过其保证容量的队列中抢占(preemption)容器。需要在 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中启用以下配置参数以支持应用程序容器的抢占。
| 属性(Property) | 描述 |
|---|---|
yarn.resourcemanager.scheduler.monitor.enable |
启用一组影响调度器的定期监视器(在 yarn.resourcemanager.scheduler.monitor.policies 中指定),默认值为 false。 |
yarn.resourcemanager.scheduler.monitor.policies |
与调度器交互的 SchedulingEditPolicy 类的列表,配置的策略需要与调度器兼容。默认值为 org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy,与 CapacityScheduler 兼容 |
当为 yarn.resourcemanager.scheduler.monitor.policies 配置 ProportionalCapacityPreemptionPolicy 类时,可以在 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中配置以下属性来控制容器的抢占:
| 属性(Property) | 描述 |
|---|---|
yarn.resourcemanager.monitor.capacity.preemption.observe_only |
若设为 true,则运行该策略,但不会通过抢占和终止(kill)事件而影响集群,默认为 false。 |
yarn.resourcemanager.monitor.capacity.preemption.monitoring_interval |
调用此 ProportionalCapacityPreemptionPolicy 策略之间的时间(单位为毫秒),默认为 3000。 |
yarn.resourcemanager.monitor.capacity.preemption.max_wait_before_kill |
从应用程序请求抢占和终止(kill)容器之间的时间(单位为毫秒),默认为 15000 |
yarn.resourcemanager.monitor.capacity.preemption.total_preemption_per_round |
用于限制每轮抢占资源的最大百分比,默认值为 0.1。通过控制此值,可以调节从集群中回收容器的速度。 在计算出总的期望抢占资源后,系统会根据此限制对资源抢占进行调整。 |
yarn.resourcemanager.monitor.capacity.preemption.max_ignored_over_capacity |
此属性定义了在目标容量之上可以忽略的最大资源量,默认值为 0.1。它形成了一个目标容量周围的死区( deadzone),有助于防止在计算出的目标平衡周围发生频繁的抢占和振荡。设置一个合适的死区可以减缓达到目标容量的时间,同时在没有自然完成的情况下,可能会阻止系统收敛到保证的容量。 |
yarn.resourcemanager.monitor.capacity.preemption.natural_termination_factor |
此属性指定了在计算的抢占目标基础上,考虑自然到期的容器并只抢占这部分差异的百分比,默认值为 0.2。这决定了系统进入死区( MAX_IGNORED_OVER_CAPACITY)的几何收敛速度。例如,终止因子为 0.5 将在 5 * #WAIT_TIME_BEFORE_KILL 之内回收近 95% 的资源,即使没有自然终止的情况下也是如此。 |
CapacityScheduler 支持 $HADOOP_HOME/etc/hadoop/capacity-scheduler.xml 中的以下配置来控制提交到队列的应用程序容器的抢占。
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.<queue-path>.disable_preemption |
此属性设置为 true 时,将以选择性地禁用提交到给定队列的应用程序容器的抢占。仅当将 yarn.resourcemanager.scheduler.monitor.enable 配置为 true,并将 yarn.resourcemanager.scheduler.monitor.policies 配置为 ProportionalCapacityPreemptionPolicy 来启用系统范围抢占时,此属性才适用。如果没有为队列设置此属性,则该属性值将从队列的父级继承。默认值为 false。 |
yarn.scheduler.capacity.<queue-path>.intra-queue-preemption.disable_preemption |
此属性设置为 true 时,将以选择性地禁用提交到给定队列的应用程序容器的队列内抢占。仅当将 yarn.resourcemanager.scheduler.monitor.enable 配置为 true,并将yarn.resourcemanager.scheduler.monitor.policies 配置为 ProportionalCapacityPreemptionPolicy 和将 yarn.resourcemanager.monitor.capacity.preemption.intra-queue-preemption.enabled 配置为 true 来启用系统范围抢占时,此属性才适用。如果没有为队列设置此属性,则该属性值将从队列的父级继承。默认值为 false。 |
3.6. 预定属性
- 预定管理与权限
CapacityScheduler 支持用如下参数来控制预定的创建、删除、更新和展示。请注意,任何用户都可以更新、删除或展示自己的预定。如果启用 预定 ACL 但未定义 预定 ACL,则每个人都可以访问预定。在下面的示例中,<queue> 是队列名。例如,可以用参数 yarn.scheduler.capacity.root.default.acl_administer_reservations 设置 预定 ACL,以便管理 default 队列上的预定。
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.root.<queue>.acl_administer_reservations |
此属性值是一个 ACL,用于指定哪些用户或组可以对指定队列的预定进行管理操作。如果给定的用户/组在给定队列上具有必要的 ACL 权限,则他们可以提交、删除、更新和列出所有的预定。如果未明确指定,该属性的 ACL 权限不会从父队列继承。 |
yarn.scheduler.capacity.root.<queue>.acl_list_reservations |
此属性值是一个 ACL,用于指定哪些用户或组可以列出指定队列的预定。如果给定的用户/组在给定队列上具有必要的 ACL 权限,则他们可以列出所有的预定。如果未明确指定,该属性的 ACL 权限不会从父队列继承。 |
yarn.scheduler.capacity.root.<queue>.acl_submit_reservations |
此属性值是一个 ACL,用于指定哪些用户或组可以向指定队列提交预定。如果给定的用户/组在给定队列上具有必要的 ACL 权限,则他们可以向给定队列提交预定。如果未明确指定,该属性的 ACL 权限不会从父队列继承。 |
3.7. 用 CapacityScheduler 配置 ReservationSystem
CapacityScheduler 支持 ReservationSystem,允许用户提前预定资源。应用程序可以在提交时指定 reservationId,以便在运行时请求预定的资源。可以在 ReservationSystem 的 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中配置以下属性。
| 属性(Property) | 必填 | 描述 |
|---|---|---|
yarn.resourcemanager.reservation-system.enable |
必填 | 是否在 ResourceManager 中启用 ReservationSystem。默认为 false,即不启用 ReservationSystem。 |
yarn.resourcemanager.reservation-system.class |
可选 | ReservationSystem 的类名。默认值是根据配置的 Scheduler 选择的,即如果配置了 CapacityScheduler,则此属性默认值是 CapacityReservationSystem。 |
yarn.resourcemanager.reservation-system.plan.follower |
可选 | 在计时器上运行的 PlanFollower 的类名,用于将 CapacityScheduler 与 Plan 互相同步。默认值是根据配置的 Scheduler 选择的,即如果配置了 CapacityScheduler,则此属性默认值是 CapacitySchedulerPlanFollower。 |
yarn.resourcemanager.reservation-system.planfollower.time-step |
可选 | PlanFollower 计时器的频率(单位为毫秒),默认值为 1000。 |
ReservationSystem 与 CapacityScheduler 队列层次结构集成,并且可以为当前的任何 LeafQueue 进行配置。 CapacityScheduler 支持用如下属性来调整 ReservationSystem:
| 属性(Property) | 必填 | 描述 |
|---|---|---|
yarn.scheduler.capacity.<queue-path>.reservable |
必填 | 向 ReservationSystem 指示队列的资源是否可为用户预定,默认为 false,即在 LeafQueues 中不启用资源预定。 |
yarn.scheduler.capacity.<queue-path>.reservation-agent |
可选 | 类名,默认为 org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.AlignedPlannerWithGreedy用于确定 ReservationAgent 的实现,该 ReservationAgent 会尝试将用户的预定请求放入 Plan 中。 |
yarn.scheduler.capacity.<queue-path>.reservation-move-on-expiry |
可选 | 用于向 ReservationSystem 指定当关联的预定过期时,是否应将应用程序移动到父级可预定队列(上面配置)中,或终止应用程序。默认为 true,表示当预定过期时将应用程序移至父级可预定队列中。 |
yarn.scheduler.capacity.<queue-path>.show-reservations-as-queues |
可选 | 是否在 Scheduler UI 中显示预定队列,默认为 false,即不显示预定队列。 |
yarn.scheduler.capacity.<queue-path>.reservation-policy |
可选 | 用于确定 SharingPolicy 实现的类名,该 SharingPolicy 将验证新预定是否不违反任何不变量。默认值为 org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacityOverTimePolicy。 |
yarn.scheduler.capacity.<queue-path>.reservation-window |
可选 | 表示 SharingPolicy 将验证计划中的约束是否得到满足的时间(单位为毫秒),默认值为 1 天。 |
yarn.scheduler.capacity.<queue-path>.instantaneous-max-capacity |
可选 | SharingPolicy 允许单个用户预定的任何时间的最大容量(以浮点数表示的百分比),默认为 1(即 100%) |
yarn.scheduler.capacity.<queue-path>.average-capacity |
可选 | 平均允许容量,将在 ReservationWindow 上以百分比形式聚合,作为 SharingPolicy 允许单个用户预定的容量百分比(浮点数表示),默认为 1(即 100%) |
yarn.scheduler.capacity.<queue-path>.reservation-planner |
可选 | 类名,用于确定 Planner 的实现,如果 Plan 容量低于(由于计划维护或节点故障)用户预定的资源,则将调用该 Planner。默认值为 org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.SimpleCapacityReplanner,它扫描计划并以相反的接受顺序 (LIFO) 贪婪地删除预定,直到预定资源在计划容量内。 |
yarn.scheduler.capacity.<queue-path>.reservation-enforcement-window |
可选 | 表示 Planner 将验证 Plan 中的约束是否得到满足的时间(单位为毫秒),默认为 1 小时。 |
3.8. 子队列的动态自动创建和管理
CapacityScheduler 支持在已配置为启用此功能的父队列下自动创建子队列。
- 实现动态创建子队列所需的队列映射设置
在 yarn.scheduler.capacity.queue-mappings 中列出的用户组队列映射需要指定一个额外的父队列参数,来标识需要在哪个父队列下创建自动创建的子队列。有关更多详细信息,请参阅上面的 基于用户与组的队列映射 部分。请注意,这种父队列还需要启用子队列的自动创建,如下面的 用于动态子队列自动创建和管理的父队列配置 部分中所述
<property>
<name>yarn.scheduler.capacity.queue-mappings</name>
<value>u:user1:queue1,g:group1:queue2,u:user2:%primary_group,u:%user:parent1.%user</value>
<description>'u:%user:parent1.%user' 映射将允许任何非 user1 的用户;
user2 将映射到其自己的用户特定叶队列,该队列将在队列parent1之下自动创建
</description>
</property>
- 父队列配置,以实现动态子队列自动创建和管理
动态队列自动创建和管理功能与 CapacityScheduler 队列层次结构集成,并且可以将当前的 ParentQueue 配置为自动创建子队列。此类父队列不支持其他预配置队列与自动创建的队列共存。 CapacityScheduler 支持用如下属性启用队列的自动创建。
| 属性(Property) | 必填 | 描述 |
|---|---|---|
yarn.scheduler.capacity.<queue-path>.auto-create-child-queue.enabled |
必填 | 指示 CapacityScheduler 是否需要为指定的父队列启用 自动子队列创建,默认为 false(即不为 ParentQueue 启用 自动子队列创建)。 |
yarn.scheduler.capacity.<queue-path>.auto-create-child-queue.management-policy |
可选 | 一个类名,用于确定 AutoCreatedQueueManagementPolicy 的实现,该类将动态管理子队列及子队列容量。默认值为 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.queuemanagement.GuaranteedOrZeroCapacityOverTimePolicy。用户或组可能使用这些子队列的时间很短,并很快停用这些子队列。因此,父队列下自动创建的子队列数量可能多于其保证容量。 当前的策略实现,会根据父队列上的容量可用性以及子队列之间的应用程序提交顺序,尽力分配已配置的容量或 0 容量。 |
- 用
CapacityScheduler配置自动创建的子队列
已启用自动创建子队列的父队列,支持配置子队列的模板参数。自动创建的队列支持除队列 ACL、绝对资源配置 之外的所有子队列配置参数。队列 ACL 则从当前父队列中继承。
| 属性(Property) | 必填 | 描述 |
|---|---|---|
yarn.scheduler.capacity.<queue-path>.leaf-queue-template.capacity |
必填 | 指定自动创建的子队列的最小保证容量。目前自动创建的子队列不支持绝对资源配置 |
yarn.scheduler.capacity.<queue-path>.leaf-queue-template.<leaf-queue-property> |
可选 | 对于可以在自动创建的子队列上配置的其他队列参数,如 maximum-capacity、user-limit-factor、maximum-am-resource-percent等,请参阅 队列属性 |
<property>
<name>yarn.scheduler.capacity.root.parent1.auto-create-child-queue.enabled</name>
<value>true</value>
<description>为队列 root.parent1 启用自动子队列创建</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.capacity</name>
<value>5</value>
<description>为队列 root.parent1 中的子队列设置容量模板参数 capacity</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.maximum-capacity</name>
<value>100</value>
<description>为队列 root.parent1 中的子队列设置容量模板参数 maximum-capacity</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.user-limit-factor</name>
<value>3.0</value>
<description>为队列 root.parent1 中的子队列设置容量模板参数 user-limit-factor</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.ordering-policy</name>
<value>fair</value>
<description>为队列 root.parent1 中的子队列设置容量模板参数 ordering-policy</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.GPU.capacity</name>
<value>50</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.accessible-node-labels</name>
<value>GPU,SSD</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.accessible-node-labels</name>
<value>GPU</value>
<description>为队列 root.parent1 中的子队列设置容量模板参数 accessible-node-labels</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.parent1.leaf-queue-template.accessible-node-labels.GPU.capacity</name>
<value>5</value>
</property>
- 用于自动创建队列管理的调度编辑策略配置 (
Edit Policy Configuration)
管理员需要在yarn.resourcemanager.scheduler.monitor.policies 配置中,将一个额外的 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.QueueManagementDynamicEditPolicy 调度编辑策略指定到当前调度编辑策略列表中,在配置中以逗号(,)分隔多个策略。有关更多详细信息,请参阅 CapacityScheduler 容器抢占。
| 属性(Property) | 描述 |
|---|---|
yarn.resourcemanager.monitor.capacity.queue-management.monitoring-interval |
调用此 QueueManagementDynamicEditPolicy 策略之间的时间(单位为毫秒),默认为 1500。 |
3.9. 其他属性
- 资源计算器(Resource Calculator)
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.resource-calculator |
ResourceCalculator 实现,用于比较调度器中的资源。 默认值 org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator 仅使用内存,而 DominantResourceCalculator 则从多个维度(如内存、CPU 等)比较调度器资源。 |
- 数据局部性(Data Locality)
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.node-locality-delay |
错过调度机会的数量(整数),在此之后 CapacityScheduler 尝试调度机架本地(rack-local)容器。通常,此属性应设置为集群中的节点数,默认为在一个机架中设置的节点数,大约为 40。 |
yarn.scheduler.capacity.rack-locality-additional-delay |
超过节点本地(node-local)延迟的额外错过的调度机会数量,在此之后 CapacityScheduler 尝试调度 off-switch 容器。默认为 -1,此时会根据公式 L * C / N 计算分配 off-switch 容器的错过调度机会的数量,其中 L 是在资源请求中指定的位置(节点或机架)数,C 是请求的容器数量,N 是集群的大小。 |
【注意】
如果YARN与文件系统分开部署,则应通过将yarn.scheduler.capacity.node-locality-delay设置为-1来禁用此功能。因为在YARN与文件系统分开部署的环境中,局部性没有意义,在这种情况下,会忽略请求中的位置约束。
- 每个
NodeManager心跳之中的容器分配
CapacityScheduler 支持用如下属性控制在每个 NodeManager 心跳中可以分配的容器数量:
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.capacity.per-node-heartbeat.multiple-assignments-enabled |
是否允许在一次 NodeManager 心跳中分配多个容器,默认为 true。 |
yarn.scheduler.capacity.per-node-heartbeat.maximum-container-assignments |
若 multiple-assignments-enabled 为 true,则在一次 NodeManager 心跳中可以分配的最大容器数量,默认为 100。将此值设置为 -1 将禁用此限制。 |
yarn.scheduler.capacity.per-node-heartbeat.maximum-offswitch-assignments |
若 multiple-assignments-enabled 为 true,则在一次 NodeManager 心跳中可以分配的 off-switch 容器的最大数量,默认为 1。 |
3.10. 检查 CapacityScheduler 的配置
在集群安装与配置完成后,可以在 YARN Web UI 里查看 CapacityScheduler 配置,步骤如下:
- 正常启动
YARN集群 - 打开
ResourceManager Web UI - 在
/scheduler中查看各个队列的资源使用情况

4. 更改队列配置
更改队列、调度器属性和添加、删除队列可以通过 2 种方式完成:文件或 API。具体的更改方式,可以用 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中的 yarn.scheduler.configuration.store.class 属性进行控制,允许的值包括:
file(默认值)将允许通过文件更改队列配置;memory将允许通过API更改队列配置(但重启后,更改失效);leveldb将允许通过API更改队列配置,并将更改存储在leveldb后端存储中;zk将允许通过API更改队列配置,并将更改存储在zookeeper后端存储中。
4.1. 通过文件更改
通过文件更改 CapacityScheduler 队列配置,需要编辑 $HADOOP_HOME/etc/hadoop/capacity-scheduler.xml,并运行 yarn rmadmin -refreshQueues 刷新队列配置。
$ vi $HADOOP_HOME/etc/hadoop/capacity-scheduler.xml
$ $HADOOP_HOME/bin/yarn rmadmin -refreshQueues
具体更改步骤为:
- 在删除子队列之前,子队列中不应有
RUNNING/PENDING的应用程序,并且必须通过更改yarn.scheduler.capacity.<queue-path>.state来停止子队列。请参阅 队列管理和权限。在删除父队列之前,其所有子队列中都不应有任何RUNNING/PENDING的应用程序,并且必须停止所有子队列,父队列也需要停止。 - 删除
$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml中的队列配置 - 运行
yarn rmadmin -refreshQueues刷新队列配置
4.2. 通过 API 更改(alpha 阶段)
通过 API 更改 CapacityScheduler 队列配置,并使用调度器配置的后端存储保存更改。要启用此功能,可以在 $HADOOP_HOME/etc/hadoop/yarn-site.xml 中配置以下属性。
【注意】
此功能处于alpha阶段,未来可能会发生变化。当通过yarn.scheduler.configuration.store.class启用调度器配置变更时,yarn rmadmin -refreshQueues将被禁用,即无法再通过文件更新CapacityScheduler队列配置。
| 属性(Property) | 描述 |
|---|---|
yarn.scheduler.configuration.store.class |
要使用的后备存储类型,默认值为 file,待选值为 memory、leveldb、zk。 |
yarn.scheduler.configuration.mutation.acl-policy.class |
可以配置 ACL 策略来限制哪些用户可以更改哪些队列,默认值为 org.apache.hadoop.yarn.server.resourcemanager.scheduler.DefaultConfigurationMutationACLPolicy,仅允许 YARN 管理员执行所有配置修改。另一个值是 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.conf.QueueAdminConfigurationMutationACLPolicy 仅当调用者是队列管理员时,才允许更改。 |
yarn.scheduler.configuration.store.max-logs |
如果使用 leveldb 或 Zookeeper,配置更改会被审计记录在后端存储中。此属性控制要存储的审计日志的最大数量(默认1000),超出此数量会删除最旧的日志。 |
yarn.scheduler.configuration.leveldb-store.path |
使用 leveldb 时配置的存储路径,默认为 ${hadoop.tmp.dir}/yarn/system/confstore。 |
yarn.scheduler.configuration.leveldb-store.compaction-interval-secs |
使用 leveldb 时压缩配置存储的时间间隔(单位为秒),默认为 86400,即 1 天。 |
yarn.scheduler.configuration.zk-store.parent-path |
使用 zookeeper 时,配置存储相关信息的 zookeeper 根节点路径,默认为 /confstore。 |
有关如何通过 REST 更改调度器配置的示例,请参阅 YARN Resource Manager REST API;有关如何通过命令行更改调度器配置的示例,请参阅 YARN Commands Reference。
5. 更新容器(实验特性)
一旦 Application Master 从 Resource Manager 接收到容器, Application Master 可以请求 Resource Manager 更新容器的某些属性。目前,仅支持 2 种类型的容器更新:
- 资源更新
Application Master可以请求Resource Manager更新容器的资源大小。例如,将容器从2GB、2vcore更新为4GB、2vcore。 - 执行类型更新
Application Master可以请求Resource Manager更新容器的ExecutionType。例如:将执行类型从GUARANTEED更改为OPPORTUNISTIC,反之亦然。
这是通过 Application Master 填充 Updated_containers 字段来实现的,该字段是 AllocateRequestProto 中 UpdateContainerRequestProto 类型的列表。Application Master 可以在同一个分配调用中发出多个容器更新请求。
UpdateContainerRequestProto 的架构(schema)如下所示:
message UpdateContainerRequestProto {
required int32 container_version = 1;
required ContainerIdProto container_id = 2;
required ContainerUpdateTypeProto update_type = 3;
optional ResourceProto capability = 4;
optional ExecutionTypeProto execution_type = 5;
}
ContainerUpdateTypeProto 是一个枚举类型:
enum ContainerUpdateTypeProto {
INCREASE_RESOURCE = 0;
DECREASE_RESOURCE = 1;
PROMOTE_EXECUTION_TYPE = 2;
DEMOTE_EXECUTION_TYPE = 3;
}
受上述枚举的限制,容器更新当前仅支持在一个更新请求中更改容器的资源更新或 ExecutionType,不能同时更新。
Application Master 还必须提供它从 Resource Manager 收到的最新 ContainerProto。这是 Resource Manager 将尝试更新的容器。如果 Resource Manager 能够更新所请求的容器,则更新后的容器将在同一分配调用或后续调用之一的 AllocateResponseProto 返回值中的 updated_containers 列表字段(列表中元素为 UpdatedContainerProto 类型,其架构如下所示)中返回。
message UpdatedContainerProto {
required ContainerUpdateTypeProto update_type = 1;
required ContainerProto container = 2;
}
它指定在 Container 上执行的容器更新的类型以及更新的 Container 对象(包含更新后的容器令牌)。然后,Application Master 可以使用容器令牌来要求相应的 NodeManager 启动容器(如果容器尚未启动),或者使用更新后的令牌来更新容器。
DECREASE_RESOURCE 和 DEMOTE_EXECUTION_TYPE 容器更新是自动的,Application Master 无需明确要求 NodeManager 减少容器的资源。而其他更新类型则需要 Application Master 明确要求 NodeManager 更新容器。如果 yarn.resourcemanager.auto-update.containers 属性值为 true(默认为 false), Resource Manager 将确保所有容器更新都是自动的。
6. 活动(Activities)
调度活动 是用于在某些关键调度路径上进行调试的活动消息,它们可以通过 RESTful API 进行记录和公开,对调度器性能影响较小。目前,支持2种类型的活动:调度器活动和应用程序活动。
6.1. 调度器活动
调度器活动 包括调度周期中有用的调度信息,这些信息说明了调度器如何分配容器。调度器活动 REST API(http://rm-http-address:port/ws/v1/cluster/scheduler/activities) 提供了一种记录调度器活动并从缓存中获取这些活动的方法。为了消除性能影响,调度器会在调度周期结束时自动禁用记录活动,可以再次查询 RESTful API 以获取最新的调度器活动。
有关查询参数、输出结构,以及有关调度器活动的示例,请参阅 YARN Resource Manager REST API。
6.2. 应用程序活动
应用程序活动 包括指定应用程序中有用的调度信息,这些信息说明了如何满足或跳过需求。应用程序活动 REST API (http://rm-http-address:port/ws/v1/cluster/scheduler/app-activities/{appid}) 提供了一种方法,可以在几秒内记录指定应用程序的应用程序活动,或从缓存中获取历史应用程序活动,可通过 actions 参数指定包括 refresh 和 get 在内的可用操作。
- 若指定
actions=refresh,将在一定时间(默认为3秒)内开启应用程序活动记录,并获得简单的响应,例如:{“appActivities”:{“applicationId”:“application_1562308866454_0001”,“diagnostic”:“Successfully received action: refresh”,“timestamp”:1562308869253,“dateTime”:“Fri Jul 05 14:41:09 CST 2019”}} - 若指定
actions=get,将不会启用应用程序活动记录,而是直接从缓存中获取历史应用程序活动记录。 - 若未指定
actions参数,则actions默认为“refresh,get”,即同时执行“refresh”与“get”。
有关查询参数、输出结构,以及有关应用程序活动的示例,请参阅 YARN Resource Manager REST API。
6.3. 活动的配置
CapacityScheduler 支持用如下属性来控制缓存大小、调度器(或应用程序)活动的到期时间。
| 属性(Property) | 描述 |
|---|---|
yarn.resourcemanager.activities-manager.cleanup-interval-ms |
活动的清理间隔(单位为毫秒),默认为 5000,即 5 秒。 |
yarn.resourcemanager.activities-manager.scheduler-activities.ttl-ms |
调度器活动的生存时长(单位为毫秒)。默认为 600000,即 10 分钟。 |
yarn.resourcemanager.activities-manager.app-activities.max-queue-length |
应用程序活动的最大队列长度,默认为 100。 |
6.4. Web UI
Resource Manager Web UI 上的应用程序尝试页面中提供了活动信息,其中汇总并显示了未完成的请求。只需点击刷新按钮即可获取最新的活动信息。




