目的

FairScheduler 是一个插件式的 Hadoop 调度器,它允许 yarn 程序在集群中以公平的方式共享资源

简介

公平调度是一种将资源分配给应用程序的方法,以便所有应用程序在一段时间内平均获得相等的资源份额。Hadoop NextGen能够调度多种资源类型。在默认情况下,公平调度程序仅基于内存调度公平决策。它可以配置为使用内存和CPU进行调度,使用Ghodsi等人开发的主导资源公平性概念。当只有一个应用程序在运行时,该应用程序将使用整个集群。当提交其他应用程序时,释放的资源被分配给新应用程序,因此每个应用程序最终得到的资源大致相同。与默认的 Hadoop 调度器(它会形成一个应用程序队列)不同,它允许短应用程序在合理的时间内完成,而不会一直等待长应用程序。在多个用户之间共享集群也是一种合理的方式。最后,公平共享还可以与应用程序的优先级一起使用——优先级被用作权重来决定每个应用程序应该获得的总资源的比例。

调度程序将应用程序进一步组织成“队列”,并在这些队列之间公平地共享资源。默认情况下,所有用户共享一个名为“default”的队列。如果应用程序在容器资源请求中特别列出一个队列,则请求将提交到该队列。还可以通过配置根据请求中包含的用户名分配队列。在每个队列中,调度策略用于在运行的应用程序之间共享资源。默认情况下是基于内存的公平共享,但是也可以配置FIFO和具有主要资源公平的多资源。可以将队列安排在层次结构中来划分资源,并使用权重进行配置以按特定比例共享集群。

除了提供公平共享之外,公平调度程序还允许将保证的最小共享分配给队列,这对于确保某些用户、组或生产应用程序始终获得足够的资源非常有用。当一个队列包含应用程序时,它至少会获得最小份额,但当队列不需要它的全部保证份额时,剩余部分将在其他运行的应用程序之间分配。这使得调度程序可以保证队列的容量,同时在这些队列不包含应用程序时有效地利用资源。

公平调度程序允许所有应用程序默认运行,但也可以通过配置文件限制每个用户和每个队列运行应用程序的数量。当用户必须一次提交数百个应用程序时,这是非常有用的,或者在一次运行太多应用程序会导致创建太多中间数据或切换太多上下文时,这通常可以提高性能。限制应用程序不会导致任何随后提交的应用程序失败,只会在调度程序的队列中等待,直到用户之前的一些应用程序完成。

具有可插拔策略的层次队列

公平调度程序支持分层队列。所有队列都从一个名为“root”的队列派生。可用资源以典型的公平调度方式分布在根队列的子队列中。然后,子队列以同样的方式将分配给他们的资源分配给他们的子队列。应用程序只能在叶队列上调度。通过将队列作为其父队列的子元素放置在公平调度程序分配文件中,可以将队列指定为其他队列的子队列。

队列的名称以其父队列的名称开头,句点作为分隔符。因此,根队列下名为“queue1”的队列将被称为 root.queue1,parent1 下的队列 queue2 称为 root.parent1.queue2。使用队列时,根节点的名称时可选的,如:queue1、parent1.queue2。

此外,公平调度程序允许为每个队列设置不同的自定义策略,以允许以用户希望的任何方式共享队列的资源。可以通过扩展 org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy 来构建自定义策略。FifoPolicy、FairSharePolicy(默认)和DominantResourceFairnessPolicy是内置的,可以直接使用。

原(MR1)公平调度器中存在的某些附加组件尚不支持。其中之一是使用自定义策略来控制优先级“提升”某些应用程序。

自动将应用程序放置到队列中

公平调度程序允许管理员配置自动将提交的应用程序放入适当队列的策略。位置可以取决于提交者的用户和组以及应用程序传递的请求队列。策略由一组规则组成,这些规则按顺序应用于对传入的应用程序进行分类。每个规则要么将应用程序放入队列,要么拒绝它,要么继续执行下一个规则。有关如何配置这些策略,请参阅下面的分配文件格式。

安装

要使用公平调度器,首先要在yarn-site.xml中分配适当的调度器类:

<property>
  <name>yarn.resourcemanager.scheduler.class</name>
  <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>

配置

自定义公平调度程序通常涉及更改两个文件。首先,可以通过在现有配置目录中的yarn-site.xml文件中添加配置属性来设置调度器范围的选项。其次,在大多数情况下,用户希望创建一个分配文件,列出存在哪些队列以及它们各自的权重和容量。分配文件每10秒重新加载一次,允许动态地进行更改。

可以放置在yarn-site.xml中的属性

Property

Description

yarn.scheduler.fair.allocation.file

分配文件的路径。分配文件是描述队列及其属性以及某些策略默认值的XML清单。该文件必须采用下一节中描述的XML格式。如果给出了一个相对路径,则在类路径(通常包括Hadoop conf目录)上搜索该文件。默认为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.8。

yarn.scheduler.fair.sizebasedweight

是否根据应用程序的大小将权重分配给各个应用程序,而不是不分大小向所有应用程序提供相等的权重。当设置为true时,应用程序的权重是1的自然对数加上应用程序请求的总内存,再除以2的自然对数。默认值为false。

yarn.scheduler.fair.assignmultiple

是否允许在一个心跳中分配多个容器。默认值为false。

yarn.scheduler.fair.dynamic.max.assign

如果assignmultiple为真,则是否动态确定可以在一个心跳中分配的资源数量。当打开时,节点上大约一半未分配的资源在一次心跳中分配给容器。默认值为true。

yarn.scheduler.fair.max.assign

如果 assignmultiple 为 true 且 dynamic.max.assign 为 false,表示在一次心跳中可以分配的容器的最大数量。默认为-1,没有设置限制。

yarn.scheduler.fair.locality.threshold.node

对于请求特定节点上的容器的应用程序,在接受另一个节点上的放置之前等待上一次容器分配之后的调度机会的数量。表示为0到1之间的浮点数,它是集群大小的一部分,表示错过调度机会的数量。默认值-1.0表示不要放弃任何调度机会。

yarn.scheduler.fair.locality.threshold.rack

对于请求特定机架上的容器的应用程序,在接受另一个机架上的放置之前等待上一次分配容器之后的调度机会的数量。表示为0到1之间的浮点数,它是集群大小的一部分,表示错过调度机会的数量。默认值-1.0表示不要放弃任何调度机会。

yarn.scheduler.fair.allow-undeclared-pools

如果是true,则可以在应用程序提交时创建新队列,这可能是因为它们是由提交者指定为应用程序的队列,也可能是因为它们是由user-as-default-queue属性放置在那里的。如果是 false,任何时候应用程序将被放置在一个没有在分配文件中指定的队列中,它将被放置在“默认”队列中。默认值为true。如果在分配文件中给出队列放置策略,则忽略此属性。

yarn.scheduler.fair.update-interval-ms

锁定调度器和重新计算公平共享、重新计算需求以及检查是否有任何东西需要抢占的间隔。默认为500毫秒。

yarn.resource-types.memory-mb.increment-allocation

fairscheduler以该值为增量授予内存。如果提交的任务的资源请求不是内存mb的倍数。增量分配,请求将四舍五入到最近的增量。默认为1024 MB。

yarn.resource-types.vcores.increment-allocation

fairscheduler将此值的增量授予vcore。如果您提交的任务带有资源请求,而不是多个vcore。增量分配,请求将四舍五入到最近的增量。默认为1。

yarn.resource-types.<resource>.increment-allocation

fairscheduler以该值为增量授予<resource>。如果提交的任务的资源请求不是<resource>的倍数。增量分配,请求将四舍五入到最近的增量。如果未为资源指定此属性,则将不应用增量汇总。如果没有指定单元,则假定资源的默认单元。

yarn.scheduler.increment-allocation-mb

yarn.resource-types.memory-mb.increment-allocation Defaults to 1024 MB.

yarn.scheduler.increment-allocation-vcores

yarn.resource-types.vcores.increment-allocation Defaults to 1.

配置文件格式

分配文件必须是XML格式的。格式包含五种类型的元素:

  • Queue elements:表示队列。队列元素可以采用一个可选属性“type”,当设置为“parent”时,它将成为一个父队列。当我们想要创建一个父队列而不需要配置任何叶队列时,这是非常有用的。每个队列元素可以包含以下属性:
  • minResources:队列有权使用的最小资源。
  • maxResources:可以分配队列的最大资源。
  • maxContainerAllocation:队列可以为单个容器分配的最大资源。
  • maxChildResources:可以最大限度地分配一个子队列的资源。
  • maxRunningApps:将队列中的应用程序数量限制为一次运行
  • maxAMShare:限制队列公平共享中可用于运行应用程序主机的部分。
  • weight:与其他队列不成比例地共享集群。权值默认为1,而具有权值2的队列接收的资源应该是具有默认权值的队列接收的资源的大约两倍。
  • schedulingPolicy:设置任何队列的调度策略。允许的值是“fifo”/“fair”/“drf”或任何扩展了org.apache.hadoop.yarn.server.resourcemanager. schedulingpolicy的类。默认为“公平”。如果“fifo”,则优先选择提交时间较早的应用程序,而如果在满足了较早的应用程序的请求后,集群上还有剩余的空间,则晚提交的应用程序可以并发运行。
  • aclSubmitApps:可以向队列提交应用程序的用户和/或组的列表。有关此列表的格式和队列acl如何工作的更多信息,请参阅下面的ACLs部分。
  • aclAdministerApps:可以管理队列的用户和/或组的列表。目前,惟一的管理操作是杀死应用程序。有关此列表的格式和队列acl如何工作的更多信息,请参阅下面的ACLs部分。
  • minSharePreemptionTimeout:在尝试抢占容器以从其他队列获取资源之前,队列的秒数低于其最小共享数。如果未设置,队列将从其父队列继承值。默认值是Long.MAX_VALUE,这意味着在设置准确值之前,它不会抢占容器。
  • fairSharePreemptionTimeout:在尝试抢占容器以从其他队列获取资源之前,队列低于公平共享阈值的秒数。如果未设置,队列将从其父队列继承值。默认值是Long.MAX_VALUE,这意味着在设置指定值之前,它不会抢占容器。
  • fairSharePreemptionThreshold:队列的公平共享抢占阈值。如果队列等待fairSharePreemptionTimeout而没有接收fairSharePreemptionThreshold*fairShare资源,则允许它抢占容器以从其他队列获取资源。如果未设置,队列将从其父队列继承值。默认值是0.5f。
  • allowPreemptionFrom:确定是否允许调度器抢占队列中的资源。默认值为true。如果队列将此属性设置为false,则此属性将递归地应用于所有子队列。
  • reservation:指示ReservationSystem队列的资源可供用户预订。这只适用于叶队列。如果未配置此属性,则叶子队列不可保留。
  • User elements:表示控制单个用户行为的设置。它们可以包含一个属性:maxRunningApps,这是对特定用户运行应用程序数量的限制。
  • A userMaxAppsDefault element:为没有指定限制的用户设置默认的运行应用程序限制。
  • A defaultFairSharePreemptionTimeout element:设置根队列的公平共享抢占超时;在根队列中被fairSharePreemptionTimeout元素覆盖。默认设置为Long.MAX_VALUE。
  • A defaultMinSharePreemptionTimeout element:设置根队列的最小共享抢占超时;被根队列中的minSharePreemptionTimeout元素覆盖。默认设置为Long.MAX_VALUE。
  • A defaultFairSharePreemptionThreshold element:设置根队列的公平共享抢占阈值;在根队列中被fairSharePreemptionThreshold元素覆盖。默认设置为0.5f。
  • A queueMaxAppsDefault element:设置队列的默认运行app限制;被每个队列中的maxRunningApps元素覆盖。
  • A queueMaxResourcesDefault element:设置队列的默认最大资源限制;在每个队列中被maxResources元素覆盖。
  • A queueMaxAMShareDefault element:设置队列的默认AM资源限制;在每个队列中被maxAMShare元素覆盖。
  • A defaultQueueSchedulingPolicy element:设置队列的默认调度策略;如果指定,则由每个队列中的schedulingPolicy元素覆盖。默认为“fair”。
  • A reservation-agent element:它设置ReservationAgent实现的类名,该实现试图将用户的预订请求放入计划中。默认值是 org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.AlignedPlannerWithGreedy
  • A reservation-policy element:它设置共享策略实现的类名,如果新的预约没有违反任何不变量,它将验证这个类名。默认值为 org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacityOverTimePolicy
  • A reservation-planner element:设置计划器实现的类名,如果计划容量低于(由于计划维护或节点故障)用户保留的资源,将调用计划器。默认值是org.apache.hadoop.yarn.server.resourcemanager. reserve .planning。SimpleCapacityReplanner,它扫描计划并贪婪地按接受顺序(LIFO)删除保留,直到保留的资源在计划容量内。
  • A queuePlacementPolicy element:它包含一个规则元素列表,告诉调度程序如何将传入的应用程序放入队列。规则按其列出的顺序应用。规则可以接受参数。所有规则都接受“create”参数,该参数指示规则是否可以创建新队列。“create”默认为true;如果设置为false,则规则会将应用程序放置在拨款文件中未配置的队列中,我们将继续下一个规则。最后一条规则必须是永远不能发出 continue 的规则。有效的规则是:
  • specified:应用程序被放入它请求的队列中。如果应用程序没有请求队列,即它指定了“default”,我们将继续。如果应用程序请求一个以句点开头或结尾的队列名,例如“”。q1”或“q1。将被拒绝。
  • user:该应用程序被放置在一个队列中,其中包含提交该应用程序的用户的名称。用户名中的句点将替换为“_dot_”,即用户的队列名“first.last”是“first_dot_last”。
  • primaryGroup:应用程序被放置在一个队列中,队列中有提交应用程序的用户的主要组的名称。组名称中的句点将替换为“_dot_”,即组“one”的队列名称。两个“是”one_dot_two”。
  • secondaryGroupExistingQueue:应用程序被放入一个队列,其名称与提交应用程序的用户的第二组匹配。将选择与配置队列匹配的第一个辅助组。组名中的句点将替换为“_dot_”,即用户名中有“1”。如果存在“one_dot_two”队列,则将其中的两个“作为辅助组之一”放置到“one_dot_two”队列中。
  • nestedUserQueue:应用程序被放置到一个队列中,用户名位于嵌套规则建议的队列之下。这与‘user’规则相似,不同之处在于‘nestedUserQueue’规则,用户队列可以在任何父队列下创建,而‘user’规则只在根队列下创建用户队列。注意,只有当嵌套规则返回父队列时,才会应用nestedUserQueue规则。可以通过将queue的“type”属性设置为“parent”来配置父队列,也可以在该队列下配置至少一个叶子,使其成为父队列。有关示例us,请参见示例分配
  • 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 name="sample_reservable_queue">
      <reservation></reservation>
    </queue>
  </queue>

  <queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>
  <queueMaxResourcesDefault>40000 mb,0vcores</queueMaxResourcesDefault>

  <!-- 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>
  <maxChildResources>4096 mb,4vcores</maxChildResources>
  </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)允许管理员控制谁可以对特定队列采取操作。它们配置了aclSubmitApps和aclAdministerApps属性,可以为每个队列设置这些属性。目前,唯一受支持的管理操作是杀死应用程序。管理员也可以向它提交申请。这些属性的值的格式类似于“user1,user2 group1,group2”或“group1,group2”。如果用户/组是队列ACL的成员或该队列的任何祖先的队列ACL的成员,则允许对队列执行操作。因此,如果queue2在queue1中,user1在queue1的ACL中,user2在queue2的ACL中,那么两个用户都可以提交到queue2。

分隔符是一个空格字符。若要仅指定ACL组,请以空格字符开始该值。

根队列的acl默认为“*”,因为acl是向下传递的,这意味着每个人都可以向每个队列提交和终止应用程序。要开始限制访问,将根队列的acl更改为“*”以外的内容。

预约及接达控制表

预订访问控制列表(acl)允许管理员控制谁可以对特定队列执行预订操作。它们配置了 acladministerreservation、aclListReservations 和 aclsubmitreservation 属性,可以为每个队列设置这些属性。目前支持的管理操作是更新和删除保留。管理员还可以提交并列出队列上的所有预订。这些属性的值的格式类似于“user1,user2 group1,group2”或“group1,group2”。如果用户/组是预订ACL的成员,则允许对队列执行操作。

注意,任何用户都可以更新、删除或列出他们自己的预订。如果启用了预订acl,但没有定义,则每个人都可以访问。

配置ReservationSystem

Fair 调度器支持 ReservationSystem,允许用户提前预约资源。应用程序可以在运行时通过在提交期间指定 reservationId 来请求保留的资源。以下配置参数可以在 yarn-site.xml 中配置。

Property

Description

yarn.resourcemanager.reservation-system.enable

强制参数:在ResourceManager中启用ReservationSystem。布尔值的预期。默认值为false,即ReservationSystem在默认情况下不启用。

yarn.resourcemanager.reservation-system.class

可选参数:ReservationSystem的类名。默认值是根据配置的调度器选择的,也就是说,如果配置了FairScheduler,那么它就是FairReservationSystem。

yarn.resourcemanager.reservation-system.plan.follower

可选参数:在计时器上运行的PlanFollower的类名,它将FairScheduler与Plan同步,反之亦然。默认值是根据配置的调度器选择的,也就是说,如果配置了FairScheduler,那么它就是FairSchedulerPlanFollower。

yarn.resourcemanager.reservation-system.planfollower.time-step

可选参数:以毫秒为单位的 PlanFollower 计时器的频率。长期价值的预期。默认值是1000。

ReservationSystem与公平调度程序队列层次结构集成,可以为叶子队列配置,也只能为叶子队列配置。详细说明 section Allocation file format 提供。

管理

公平调度提供了支持管理在运行时通过一些机制:

在运行时修改配置

通过编辑分配文件,可以在运行时修改最小共享、限制、权重、抢占超时和队列调度策略。调度器将在看到文件被修改后10-15秒重新加载该文件。

通过web UI进行监视

可以通过ResourceManager的web界面(http://*ResourceManager URL*/cluster/scheduler)查看当前的应用程序、队列和公平共享。

在web界面上每个队列可以看到以下字段:

  • Used Resources - 分配给队列内容器的资源总和。
  • Num Active Applications - 队列中已接收至少一个容器的应用程序的数量。
  • Num Pending Applications - 队列中尚未接收任何容器的应用程序的数量。
  • Min Resources - 保证队列的已配置的最小资源。
  • Max Resources - 配置了允许队列使用的最大资源。
  • Instantaneous Fair Share - 队列的即时公平资源共享。这些共享只考虑活动队列(那些运行应用程序的队列),并用于调度决策。当其他队列不使用队列时,可能会将资源分配到它们的共享之外。一个队列的资源消耗等于或低于它的瞬时公平份额,它的容器永远不会被抢占。
  • Steady Fair Share - 队列中稳定的公平资源份额。这些共享考虑所有队列,而不管它们是否处于活动状态(具有正在运行的应用程序)。它们的计算频率较低,只有在配置或容量发生变化时才会更改。它们的目的是提供对用户期望的资源的可见性,并因此显示在Web UI中。

在队列之间移动应用程序

公平调度程序支持将运行中的应用程序移动到不同的队列。这对于将重要的应用程序移动到高优先级队列或将不重要的应用程序移动到低优先级队列非常有用。应用程序可以通过运行 yarn 应用程序 -movetoqueue appID -queue targetQueueName 来移动。

当应用程序被移动到队列时,为了确定公平性,它的现有分配将与新队列的分配一起计算,而不是与旧队列的分配一起计算。如果将应用程序的资源添加到队列将违反其 maxRunningApps 或 maxResources 约束,则尝试将应用程序移动到队列将失败。

转储公平调度程序状态

公平调度程序能够定期转储其状态。默认情况下是禁用的。管理员可以通过设置org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler来启用它。状态日志级别调试。

在默认情况下,公平调度程序日志将转到资源管理器日志文件。公平调度器状态转储可能会生成大量日志数据。取消log4j中“公平调度程序状态转储”部分的注释属性将状态转储到单独的文件中。