介绍
公平调度是一种对于全局资源, 对于所有应用作业来说, 都均匀分配的资源分配方法 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 限制与要移动的作业冲突, 那么作业移动会失败
来源: https://yq.aliyun.com/articles/433892