YARN调度器

本文介绍YARN调度器。

简介

Hadoop YARN的核心组件是ResourceManager,负责集群资源管理与调度,而ResourceManager组件的核心是调度器,负责统筹集群资源,满足应用的资源需求。调度器不仅需要优化整个集群的资源布局,避免热点等问题对应用的影响,最大程度利用集群资源;还要能协调好大量应用在集群的运行,基于多租户(队列)公平性、应用优先级等策略解决好资源竞争等问题;也要能满足个别应用在节点依赖、放置策略等方面的特殊需求。

YARN调度器是可拔插的插件,主要有FIFOScheduler、FairScheduler和CapacityScheduler三类。

  • FIFOScheduler:是最简单的调度器,不支持多租户(所有应用都提交到Default队列),不考虑集群的资源分布(节点上堆叠调度),只支持以FIFO(First In,First Out)策略依次调度应用,无其他控制与调度特性。只适用于及其简单的场景,因此很少应用于正式生产。

  • FairScheduler:是CDH(Cloudera Distributed Hadoop)的默认调度器,与HDP(Hortonworks Data Platform)合并后的CDP(Cloudera Data Platform)不再使用(迁移到CapacityScheduler),Apache Hadoop社区也建议迁移到CapacityScheduler。FairScheduler支持较为完善的多租户管理与资源调度能力,包括多级队列、配额管理、ACL控制、弹性资源共享、租户间公平性调度策略、租户内应用调度策略、资源预留、抢占、异步调度等,然而在Apache Hadoop社区的发展相比CapacityScheduler仍稍显落后,核心调度未考虑整个集群的资源布局,也不支持Node Labels(分区调度)、Node Attributes(节点打标调度)、Placement Constraints(放置约束)等调度特性。

  • CapacityScheduler:是Apache Hadoop社区、HDP(Hortonworks Data Platform)及合并后CDP(Cloudera Data Platform)的默认调度器,具有最完善的多租户管理与资源调度能力,不仅包含了FairScheduler的全部能力,还能协调好整个集群的资源布局(基于Global Scheduling),减少热点概率,最大程度利用集群资源,还支持Node Labels(分区调度)Node Attributes(节点打标调度)、Placement Constraints(放置约束)等调度特性。

因此,EMR YARN推荐并默认使用CapacityScheduler,下面重点对CapacityScheduler进行介绍,其他调度器的使用说明请参考社区文档。

基础架构&核心流程

CapacityScheduler的主调度流程有三种触发方式:

  • 节点心跳驱动(Node-Heartbeat Driven):是面向节点的局部调度(当调度器收到每个节点心跳时触发,为当前节点选择可调度的应用),受限于心跳间隔时间与接近随机调度,可能有较大比例的节点调度因资源不足、调度需求不满足等原因未命中,调度效率较差。通常适用于调度性能和调度功能要求都不高的集群。

  • 异步调度(Async Scheudling):由独立的异步调度线程触发(支持多线程),每轮调度从节点列表中随机挑选一个节点开始,调度性能较高。通常适用于调度性能要求较高、调度功能要求不高的集群。

  • 全局调度(Global Scheduling):由独立的全局调度线程触发,是面向应用的全局调度。每轮调度考虑多租户公平性、应用优先级等因素依次选择应用,根据应用的资源大小、调度需求、资源分布等因素从集群中挑选最合适的节点,从而作出相对更优的调度决策。适用于调度性能和调度功能要求都较高的集群。

下图是基于YARN v3.2+全局调度的基础架构:2

  • 主调度(MainScheduler):是基于资源请求的异步多线程处理框架,内部包含分配线程和提交线程,一个或多个分配线程负责定位优先级最高的资源请求,根据其资源大小及摆放约束批量选择合适的候选节点,生成分配提案放入中间队列,由单个提交线程进行消费,重新检查各种约束后成功提交或驳回,同时更新调度器状态。

  • 重调度(ReScheduler):是周期性运行的动态资源监测框架,内部有多个资源监测策略,包括队列间抢占、队列内抢占和预留资源抢占等。

  • 节点排序管理器(Nodes Sorting Manager)与放置约束管理器(Placement Constraints Manager):是主调度框架中全局调度(Global Scheduling)的扩展插件,针对主调度框架中的负载均衡和复杂摆放约束功能的扩展插件。

CapacityScheduler全局调度模式的主要流程如下:3

  • 主调度分配流程:

    1. 选择Partition(node label):集群可能存在一个或多个Partition,多个Partition之间轮流进行分配。

    2. 选择Leaf Queue:从顶层Root Queue开始逐层深入,同一层级的子Queue按保障资源使用比例从低到高顺序依次遍历,直到锁定Leaf Queue。(如上图中的树状图,红色表示GUARANTEED资源使用率较高,绿色表示GUARANTEED资源使用率较低,优先为绿色状态的Queue分配资源)。

    3. 选择App:Queue内部App选择支持Fair与Fifo两种策略,其中Fair策略支持按已分配内存资源(从小到大)的顺序依次选择,Fifo策略支持按应用优先级(从高到低)和应用ID(从小到大)的顺序依次选择。

    4. 选择Request:根据Request优先级依次选择。

    5. 选择Sorted Candidate Nodes:根据Request摆放约束条件从排序好的全部Nodes筛选出符合资源请求需求的Candidate Nodes。

    6. 遍历Candidate Nodes并试图为每个Node分配一个Container,分配过程需检查queue/nodeallocated/used/unconfirmed资源,检查通过后产生一个Allocation Proposal,放入Proposal Queue。

  • 主调度提交流程:单独的提交线程从Proposal Queue中取出Allocation Proposal进行最终校验,重新检查应用需求、节点资源、放置约束条件等是否仍然满足,不通过直接丢弃,通过后本次分配正式生效(应用或节点资源更新)。

  • 重调度抢占流程:当集群整体资源紧张(超出一定水位)且有应用资源请求未满足时,重调度流程将从多个维度考虑实施抢占,包括:

    • 队列间抢占:YARN允许队列未用完的GUARANTEED资源(Capacity以内是GUARANTEED资源)被其他队列共享使用(Capacity ~ max-capacity部分是共享资源),因此当GUARANTEED资源未满足的队列下面的应用有资源需求,但集群无空闲资源时需要触发队列间抢占。

    • 队列内抢占:根据队列的分配配置策略(Fifo或Fair)监测并调整应用资源公平性,当高优先级应用有资源需求但队列资源用满时需要触发队列内抢占。

    • 预留任务抢占:当预留任务满足一定条件(例如超时未分配完成)时释放预留任务及被其占用的资源。

主要特性

CapacityScheduler具备如下的特性:

  • 多级队列(树形结构):支持多级租户管理,父队列资源配额能够限制其下所有子队列的资源使用,单个子队列的资源配额也不能超过父队列的资源配额,因此对于多租户管理具备较高的可控性,能够满足各种复杂应用场景的需求。

  • 资源配额:每个队列都需配置Capacity与MaxCapacity资源,其中Capacity指的是保障资源,MaxCapacity是最大可用资源。 除了资源维度的配额,还可以为队列配置运行应用数上限、AM资源使用最大比例、用户资源使用比例等,从应用、任务类型、用户等多个维度进行控制。

  • 弹性资源共享:队列的弹性资源量=(MaxCapacity - Capacity),集群与父队列有空闲资源时,子队列可以利用其他队列的空闲(未被使用)保障资源,从而支持不同队列资源分时复用,提升集群的资源利用率。

  • ACL控制:每个队列均可以支持较为严格的权限控制,可以指定允许提交和管理任务的用户,可以配置相同用户管理多个队列。

  • 租户间公平性调度策略:租户间公平性是指对处于同一层级的队列(父队列相同),调度时按各个队列保障资源的使用比例从低到高的顺序进行,优先满足保障资源用量少的队列的资源使用需求。如果配置了队列优先级,同一层级的队列首先将分为两组,保障组(已使用资源小于等于保障资源)与超用组(已使用资源大于保障资源),调度时优先为保障组分配资源,两组内部的所有队列再按优先级从大到小、保障资源使用比例从小到大进行排序,依次为其分配资源。

  • 租户内应用调度策略:租户内应用调度策略主要包括Fifo与Fair两种,Fifo即先入先出调度,对所有应用按优先级从高到低、提交时间从前往后的顺序排序,Fair是公平调度,对所有应用按资源使用比例从小到大、提交时间从前往后的顺序排序。

  • 抢占:运行时集群的资源一直变化,为了保障弹性资源共享、租户间公平性调度策略与租户内应用调度策略的要求,需要依赖抢占流程来平衡各队列、各应用的资源使用。

配置与使用说明

全局配置

配置文件

配置项

(推荐)配置值

说明

yarn-site.xml

yarn.resourcemanager.scheduler.class

不配置(默认使用CapacityScheduler)。

Scheduler插件类,默认值:org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler。

capacity-scheduler.xml

yarn.scheduler.capacity.maximum-applications

不配置(默认10000)。

集群可同时运行的最大应用数,默认值:10000。

yarn.scheduler.capacity.global-queue-max-application

不配置 (按Capacity占集群总资源的比例折算,如果有非常规需求的多个队列,如Capacity配置很小但应用数很多,可以更新该配置项)。

队列默认可同时运行的最大应用数。如果未配置,则将集群同时运行的最大应用数按比例分配到每个队列,即:每个队列下可同时运行的最大应用数 = queueCapacity/clusterResource * ${yarn.scheduler.capacity.maximum-applications}。

yarn.scheduler.capacity.maximum-am-resource-percent

0.25

队列默认的AM可用比例,即队列内所有应用的AM占用资源量不得超过(该配置项值 * 队列Max-Capacity),默认值:0.1(若队列内小应用较多,AM Container占比较高,会导致可运行应用数受限,因此可适当调大)。

yarn.scheduler.capacity.resource-calculator

org.apache.hadoop.yarn.util.resource.DominantResourceCalculator

资源计算类,用于队列、节点、应用的各类资源运算(影响调度器的各个环节),默认org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator,只考虑内存资源(不考虑CPU资源)。另外有org.apache.hadoop.yarn.util.resource.DominantResourceCalculator可选,默认同时考虑配置的全部资源类型(包括内存、CPU和其他自定义资源类型,使用多的为主资源)。

yarn.scheduler.capacity.node-locality-delay

-1

考虑节点本地化而延迟调度的次数,默认值:40,通常用于Hadoop早期调度时重度依赖本地存储的场景(将任务分配到依赖数据所在的节点),随着网络与存储的发展,磁盘与网络不再是主要瓶颈,因此一般应用都不需再考虑本地化问题,建议配置为-1,可大幅提升调度性能。

节点调度配置

配置集

配置项

(推荐)配置值

说明

capacity-scheduler.xml

yarn.scheduler.capacity.per-node-heartbeat.multiple-assignments-enabled

false

节点心跳驱动模式:开启一次心跳分配多个Container,默认值:true,由于对整个集群的负载均衡影响较大(容易造成热点),建议不开启。

yarn.scheduler.capacity.per-node-heartbeat.maximum-container-assignments

不配置

节点心跳驱动模式:一次心跳的最大分配数量,默认值:100,仅在开启一次心跳分配多个Container时有效。

yarn.scheduler.capacity.per-node-heartbeat.maximum-offswitch-assignments

不配置

节点心跳驱动模式:一次心跳分配的最大非Locality的分配数量,仅在开启一次心跳分配多个Container时有效。

yarn.scheduler.capacity.schedule-asynchronously.enable

true

异步调度:是否开启,默认值:false,建议开启以提升调度性能。

yarn.scheduler.capacity.schedule-asynchronously.maximum-threads

不配置

异步调度:最大分配线程数,默认值:1,多个分配线程可能产生大量重复Proposal,通常1个分配线程已经具备了很高的调度性能,因此建议不配置。

yarn.scheduler.capacity.schedule-asynchronously.maximum-pending-backlogs

不配置

异步调度:Proposal队列等待提交Allocation Proposal的最大数量,默认值:100,集群规模较大可适当上调此配置值。

yarn.scheduler.capacity.multi-node-placement-enabled

不配置

全局调度:是否开启全局调度(面向多节点分配),默认值:false,调度性能和调度功能要求都较高的集群可开启使用。

yarn.scheduler.capacity.multi-node-sorting.policy.names

不配置

全局调度:多节点排序策略名,启用全局调度时可配置:resource-based,并增加策略类配置项:yarn.scheduler.capacity.multi-node-sorting.policy.resource-based.class=org.apache.hadoop.yarn.server.resourcemanager.scheduler.placement.ResourceUsageMultiNodeLookupPolicy

yarn.scheduler.capacity.node-locality-delay

-1

考虑节点本地化而延迟调度的次数,默认值:40,通常用于Hadoop早期调度时重度依赖本地存储的场景(将任务分配到依赖数据所在的节点),随着网络与存储的发展,磁盘与网络已基本不是瓶颈,因此一般应用都不需再考虑本地化问题,建议配置为-1,可大幅提升调度性能。

节点分区配置

更多内容,请参见Node Labels特性使用

队列基础配置

队列基础配置包括队列的层级关系、Capacity与MaxCapacity配置。假如一个YARN集群同时被公司多个组织、团队共享使用,我们可以根据具体的组织方式及预期资源占比来规划YARN队列,如下图所示,一级队列包括dev、test、support、default四个队列,保障资源比例分别是50%、30%、10%和10%,最大资源比例分别是100%、50%、30%、100%,其中dev队列下级分为training和services,保障资源比例分别是40%和60%,最大资源比例都是100%。4

相关配置如下表。

配置集

配置项

(示例)配置值

说明

capacity-scheduler.xml

yarn.scheduler.capacity.root.queues

dev,test,support,default

Root子队列,多个队列时以英文半角逗号(,)分隔。

yarn.scheduler.capacity.root.dev.capacity

50

Root.dev队列保障资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.dev.maximum-capacity

100

Root.dev队列最大可用资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.dev.queues

training,services

Root.dev队列的子队列。

yarn.scheduler.capacity.root.dev.training.capacity

40

Root.dev.training队列保障资源百分比(相对于Root.dev保障资源)。

yarn.scheduler.capacity.root.dev.training.maximum-capacity

100

Root.dev.training队列最大资源百分比(相对于Root.dev最大资源)。

yarn.scheduler.capacity.root.dev.services.capacity

60

Root.dev.services队列保障资源百分比(相对于Root.dev保障资源)。

yarn.scheduler.capacity.root.dev.services.maximum-capacity

100

Root.dev.services队列最大资源百分比(相对于Root.dev最大资源)。

yarn.scheduler.capacity.root.test.capacity

30

Root.test队列保障资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.test.maximum-capacity

50

Root.test队列最大可用资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.support.capacity

10

Root.support队列保障资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.support.maximum-capacity

30

Root.support队列最大可用资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.default.capacity

10

Root.default队列保障资源百分比(相对于集群资源)。

yarn.scheduler.capacity.root.default.maximum-capacity

100

Root.default队列最大可用资源百分比(相对于集群资源)。

YARN Scheduler页面的树状列表能够显示各个队列的层级结构及其保障资源与最大资源。如下图所示,灰色框代表各队列的最大资源百分比,其中的虚线框代表队列的保障资源百分比(均相对于集群总资源),叶子队列展开能看到它的详细信息,如队列状态、各种资源信息(所有Application Master跟User的已使用、配置、实际生效、资源、百分比等)、应用信息(应用数、任务数等)与配置信息(最大应用数、用户最大应用数、NodeLabels、是否开启抢占、默认应用优先级等)。5

队列高级配置

配置集

配置项

(推荐)配置值

说明

capacity-scheduler.xml

yarn.scheduler.capacity.<queue_path>.ordering-policy

fair

指定队列内应用调度策略,包括fifo与fair两种,fifo即先入先出调度,对所有应用按优先级从高到低、提交时间从前往后的顺序排序,fair是公平调度,对所有应用按资源使用比例从小到大、提交时间从前往后的顺序排序。默认值:fifo, 一般应用场景配置成fair更合适。

yarn.scheduler.capacity.<queue-path>.ordering-policy.fair.enable-size-based-weight

不配置

基于权重的fair调度策略(启用fair调度策略时是否考虑应用需求),默认值:false。false表示按Used资源值从小到大排序, true表示按照(used/demand)计算值从小到大排序,可在资源竞争时尽量避免资源较多的大应用资源告急。

yarn.scheduler.capacity.<queue_path>.state

不配置

指定队列状态,默认值:RUNNING。通常不需要配置,只有在需要删除队列的时候,修改指定队列的状态为STOPPED,待队列下应用全部结束后队列将会被自动删除。

yarn.scheduler.capacity.<queue_path>.maximum-am-resource-percent

不配置

队列默认的AM可用比例,即队列内所有应用的AM占用资源量不得超过(该配置项值 * 队列max-capacity),默认值:${yarn.scheduler.capacity.maximum-am-resource-percent}。

yarn.scheduler.capacity.<queue_path>.user-limit-factor

不配置

指定队列内单个用户的资源上限因子,队列内单个用户最大可用资源=min(队列最大资源, 队列保障资源 * userLimitFactor),默认值:1.0。

yarn.scheduler.capacity.<queue_path>.minimum-user-limit-percent

不配置

指定队列内单个用户的最小资源比例(相对于队列保障资源),队列内单个用户的资源限制=max(队列保障资源/用户数, 队列保障资源 * minimumUserLimitPercent / 100), 默认值:100。

yarn.scheduler.capacity.<queue_path>.maximum-applications

不配置

指定队列最大运行应用数,若不配置,则队列最大运行应用数 = 队列保障资源比例 * ${yarn.scheduler.capacity.maximum-applications}。

yarn.scheduler.capacity.<queue_path>.acl_submit_applications

不配置

指定队列的应用提交ACL,不配置则继承上级队列的配置,Root队列默认允许全部用户。

yarn.scheduler.capacity.<queue_path>.acl_administer_queue

不配置

指定队列的管理ACL,不配置则继承上级队列的配置,Root队列默认允许全部用户。

队列ACL配置

队列ACL相关配置如下,一般情况可以不开启ACL控制,后续有相应的场景需求再开启。

配置集

配置项

(推荐)配置值

说明

yarn-site.xml

yarn.acl.enabled

不配置

是否开启ACL,默认值:false。

capacity-scheduler.xml

yarn.scheduler.capacity.<queue_path>.acl_submit_applications

不配置

指定队列的应用提交ACL,不配置则继承上级队列的配置,Root队列默认允许全部用户。

yarn.scheduler.capacity.<queue_path>.acl_administer_queue

不配置

指定队列的管理ACL,不配置则继承上级队列的配置,Root队列默认允许全部用户。

说明
  • 父队列的ACL配置能对所有子队列生效。例如,只配置了root.default队列允许hadoop用户提交作业,其他用户仍然能够向root.default队列提交应用,因为Root默认允许所有用户提交与管理队列,因此使用队列的ACL,必须先将Root队列的ACL配置设置都不允许:yarn.scheduler.capacity.root.acl_submit_applications=<space>, yarn.scheduler.capacity.root.acl_administer_queue=<space>

  • 提交应用和转移应用(到其他Queue)的ACL权限不是只由配置项yarn.scheduler.capacity.<queue_path>.acl_submit_applications管理,在yarn.scheduler.capacity.<queue_path>.acl_administer_queue中配置的相关组或用户也具备提交应用(转移应用)权限。

抢占配置

抢占是为了保证多租户公平性、应用优先级等需求的运行时重调度,对调度要求较高的集群可以选择开启抢占(v2.8.0+版本支持),相关配置项如下:

配置集

配置项

(推荐)配置值

说明

yarn-site.xml

yarn.resourcemanager.scheduler.monitor.enable

true

抢占功能总开关。

capacity-scheduler.xml

yarn.resourcemanager.monitor.capacity.preemption.intra-queue-preemption.enabled

true

队列内抢占开关(队列间抢占无开关,默认开启)。

yarn.resourcemanager.monitor.capacity.preemption.intra-queue-preemption.preemption-order-policy

priority_first

抢占策略优先考虑应用优先级,默认值:userlimit_first。

yarn.scheduler.capacity.<queue-path>.disable_preemption

true

指定队列不可被抢占,不配置则默认使用上级队列的配置,例如给root队列配置为true,则所有子队列均不可抢占(root队列不配置则默认为false,即可以被抢占)。

yarn.scheduler.capacity.<queue-path>.intra-queue-preemption.disable_preemption

true

指定队列禁用队列内抢占,不配置则默认使用上级队列的配置,例如给root队列配置为true,则所有子队列均禁用队列内抢占。

REST API管理capacity-scheduler.xml配置

capacity-scheduler.xml配置管理原本只支持RPC调用RefreshQueues接口,每次调用需基于全量配置内容,且无法获取当前更新生效的配置项,从v3.2.0版本开始支持REST API接口增量更新和查看capacity-scheduler.xml当前已生效的全部配置,极大地方便了队列管理。

如需启用,可参考以下配置项:

配置集

配置项

(推荐)配置值

说明

yarn-site.xml

yarn.scheduler.configuration.store.class

fs

使用FileSystem类型存储。

yarn.scheduler.configuration.max.version

100

保留历史版本的最大数量(超出自动清理:FIFO)。

yarn.scheduler.configuration.fs.path

/yarn/<集群名>/scheduler/conf

Capacity-scheduler.xml文件存储路径(不存在则自动创建,不指定前缀则默认DefaultFs相对路径)。

重要

将<集群名>替换为集群名称以便区分(可能有多个YARN集群对应同一分布式存储)。

  • 启用后查看capacity-scheduler.xml配置的方式:

    • REST API:http://<rm-address>/ws/v1/cluster/scheduler-conf。

    • HDFS文件:${yarn.scheduler.configuration.fs.path}/capacity-scheduler.xml.<timestamp>,<timestamp>最大的是最新配置。

  • 更新配置示例:

    更新一个配置项yarn.scheduler.capacity.maximum-am-resource-percent=0.2,并删除一个配置项yarn.scheduler.capacity.xxx,删除某配置项只需去掉参数值。

    curl -X PUT -H "Content-type: application/json" 'http://<rm-address>/ws/v1/cluster/scheduler-conf' -d '
    {
      "global-updates": [
        {
          "entry": [{
            "key":"yarn.scheduler.capacity.maximum-am-resource-percent",
            "value":"0.2"
          },{
            "key":"yarn.scheduler.capacity.xxx"
          }]
        }
      ]
    }'

单任务/容器(Container)资源限制

单任务/容器(Container)的资源限制由以下调度器或队列配置项决定:

配置集

配置项

配置说明

默认值/规则

yarn-site.xml

yarn.scheduler.maximum-allocation-mb

集群级最大可调度内存资源,单位MiB。

EMR默认值为:创建集群时最大非Master实例组的可用内存(与最大实例组的 yarn.nodemanager.resource.memory-mb配置值相同)。

yarn.scheduler.maximum-allocation-vcores

集群级最大可调度CPU资源,单位VCore。

EMR默认值为32。

capacity-scheduler.xml

yarn.scheduler.capacity.<queue-path>.maximum-allocation-mb

指定队列的最大可调度内存资源,单位MiB。

默认未配置,配置则覆盖集群级配置,仅对指定队列生效。

yarn.scheduler.capacity.<queue-path>.maximum-allocation-vcores

指定队列的最大可调度CPU资源,单位VCore。

默认未配置,配置则覆盖集群级配置,仅对指定队列生效。

如果申请资源超过单任务/容器(Container)最大可用资源配置,则在应用日志中能够发现以下异常信息:InvalidResourceRequestException: Invalid resource request…