本文档描述了Fair Scheduler
,这是一个可插拔的Hadoop调度器,它允许YARN应用在大型集群中公平地共享资源。
FairScheduler 运行流程图
公平调度器的运行流程就是RM去启动FairScheduler,SchedulerDispatcher两个服务,这两个服务各自负责update线程,handle线程。
(1)更新各个队列的资源(Instantaneous Fair Share);
(2)判断各个leaf队列是否需要抢占资源(如果开启抢占功能)
Fair Scheduler
是一种将资源分配给应用的方法,以便所有应用在一段时间内平均获得相等的资源份额。Hadoop NextGen
能够调度多种资源类型。在默认情况下,公平调度程序仅基于内存调度公平决策。它可以配置为使用内存和CPU进行调度,使用Ghodsi等人开发的主导资源公平性概念。当只有一个应用程序在运行时,该应用程序将使用整个集群。当提交其他应用程序时,释放的资源被分配给新应用程序,因此每个应用程序最终得到的资源大致相同。与默认的Hadoop调度器(它会形成一个应用程序队列)不同,它允许短应用程序在合理的时间内完成,而不会饿死长应用程序。在多个用户之间共享集群也是一种合理的方式。最后,公平共享还可以与应用程序的优先级一起使用——优先级被用作权重来决定每个应用程序应该获得的总资源的比例。
调度程序将应用进一步组织成队列,并在这些队列之间公平地共享资源。默认情况下,所有用户共享一个名为default的队列。如果应用在容器资源请求中特别列出一个队列,则请求将提交到该队列。还可以通过配置根据请求中包含的用户名分配队列(配置不同的分配规则)。在每个队列中,调度策略用于在运行的应用之间共享资源。缺省情况下是基于内存的公平共享,但是也可以配置FIFO和具有主要资源公平的多资源。可以将队列安排在层次结构中来划分资源,并使用权重进行配置以按特定比例共享集群。
除了提供公平共享之外,公平调度程序还允许将保证的最小共享资源分配给队列,这对于确保某些用户、组或生产应用始终获得足够的资源非常有用。当一个队列包含应用程序时,它至少会获得最小份额,但当队列不需要它的全部保证份额时,剩余部分将在其他运行的应用之间分配。这使得调度程序即可以保证队列的容量,同时也在这些队列不包含应用时有效地利用资源。
公平调度器允许所有应用以默认方式运行(即共享内存),但也可以通过配置文件限制每个用户和每个队列运行应用的数量。当用户必须一次提交数百个应用时,或者一次运行太多应用导致创建太多中间数据或切换太多上下文时,非常有用。这通常可以提高性能。限制应用不会导致任何随后提交的应用失败,只会在调度程序的队列中等待,直到用户之前的一些应用完成。
公平调度程序支持分层队列。所有队列都从一个名为root的队列派生。可用资源以典型的公平调度方式分布在根队列的子队列中。然后,子队列以同样的方式将它们的资源分配其子队列。应用只能在叶子队列(将队列层级看作为层级树)上调度。在公平调度器配置文件中,通过将子队列设置为其父队列的子元素,构建队列层级关系。
队列的名称以其父队列的名称开头,句点作为分隔符。因此,根队列下名为“queue1”的队列将被称为“queue1”。队列“parent1”下名为“queue2”的队列称为“root.parent1.queue2”。当提到队列时,名称的根部分是可缺省的。
公平调度程序允许为每个队列设置不同自定义策略,允许用户以其希望的方式共享队列的资源。通过扩展org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy
来构建自定义策略。FifoPolicy
、FairSharePolicy
(默认)和DominantResourceFairnessPolicy
是内置调度策略。
公平调度器允许管理员配置自动将提交的应用程序放入适当队列的策略。位置可以取决于提交者的用户和组以及应用程序传递的请求队列。策略由一组规则组成,这些规则按顺序应用于对传入的应用程序进行分类。每个规则要么将应用程序放入队列,要么拒绝它,要么继续执行下一个规则。有关如何配置这些策略,请参阅下面的分配文件格式。
要使用公平调度程序,请首先在yarn-site.xml中分配适当的调度程序类:
<property>
<name> yarn.resourcemanager.scheduler.class </name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler </ value>
</property>
自定义公平调度程序通常涉及更改两个文件:
属性名称 | 描述 |
---|---|
yarn.scheduler.fair.allocation.file | 调度器分配规则的配置文件路径,描述队列及其属性以及某些策略默认值的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时,应用的权重是应用的所有请求内存的自然对数加权,除以以2为底的自然对数。。默认值为false。 |
yarn.scheduler.fair.assignmultiple | 是否允许一次心跳中分配多个容器。默认值为false。 |
yarn.scheduler.fair.dynamic.max.assign | 如果true,设置可以在一次心跳中分配的容器的最大数量。默认为-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,则可以在应用提交时创建新队列,无论是application指定了队列,或者是按照user-as-default-queue放置到相应队列。如果该值为false,则每当应用程序被放置在未在分配文件中指定的队列中时,它都会被放置在default队列中,禁止用户自己创建队列。默认为true。如果在分配文件中给定了队列放置策略,则忽略此属性。 |
yarn.scheduler.fair.update-interval-ms | 默认值500ms,锁住调度器重新进行计算作业所需资源的间隔 |
配置文件必须为XML格式。格式包含五种类型的元素:
fairsharepreemptionTimeout
而未收到fairsharepreemptionThreshold*fairshare资源,则允许抢占容器以从其他队列获取资源。如果未设置,则队列将从其父队列继承值。以下给出 allocation file的一个样例:
<?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_queue' 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>
访问控制列表(ACLs)允许管理员控制谁能对特定队列执行操作。这些用户通过aclSubmitApps 和aclAdministerApps属性配置,可以设置在每个队列上。当前唯一支持的管理性操作就是杀死app。任何能够管理管理的人也都可以向该队列提交app.这些属性的值像 “user1,user2 group1,group2” 或者“ group1,group2”的格式。如果用户或者组是在队列的ACLs中或者在这个队列的任意祖先的ACLs中,那么他对该队列的操作是被允许的。所以,如果queue2 在queue1内部,并且user1 在queue1的ACL中,user2 在queue2的ACL中,那么两个用户都可以向queue2提交app.
备注:分隔符是空格。要只是指定ACL组,该值需要以空格开头.
root队列的ACLS默认是"* ",因为ACLs是向下传递的,意思是每个用户都可以对每一个队列提交和杀死application。要启动严格的方访问,修改root队列的ACL为除"*"之外的其他值.
通过编辑allocation file可以在运行时完成修改最小共享,资源限制,权重,超时抢占以及队列调度策略等。调度器会每个10-15秒重载修改后的该配置文件.
当前应用、队列以及公平共享都可以通过ResourceManager的web UI查看,地址在http://ResourceManagerURL/cluster/scheduler。
在web UI上可以看到每个队列的以下字段:
Fair Scheduler 支持移动一个运行中的应用程序到另外一个队列。这个可以用于移动一个重要的应用程序到较高优先级队列,或者移动一个不重要的应用程序到一个较低优先级的队列。通过运行 :
yarn application -movetoqueue appID -queue targetQueueName可以移动运行中的应用程序。
当应用程序移动到一个队列,出于公平考虑,它的现存的分配计算会变成新队列的资源分配。如果加入被移动的应用程序的资源超出目标队列的maxRunningApps 或者maxResources 限制,本次移动将会失败。
Fair Scheduler能够定期转储其状态。默认情况下禁用。管理员可以通过将:
org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler.statedump
日志记录级别设置为DEBUG 来启用它。
默认情况下,Fair Scheduler日志进入资源管理器日志文件。公平调度程序状态转储可能会生成大量日志数据。取消注释log4j.properties中的“公平调度程序状态转储”部分,以将状态转储到单独的文件中。
内容来源于网络,如有侵权,请联系作者删除!