揭秘Apache Hadoop YARN,第5部分:使用FairScheduler队列属性[译]

在之前的第4部分中,我们描述了Apache Hadoop中最常用的FairScheduler属性。在第5部分中,我们将提供一些示例来展示如何单独或组合使用属性,以实现通常所需的行为,如应用程序优先级和组织队列。

示例:Best Effort队列

摘要:创建一个“best effort”队列,当群集空闲时执行应用程序。

实现:在FairScheduler中,如果一个队列权重位0.0,只有群集中有空余资源的时候才会去运行应用程序。换句话说,priority_jobs队列中的所有作业将首先被分配,然后FairScheduler才会将剩下的资源分配给best_effort_jobs队列。

<queue name=”priority_jobs”>
</queue>
<queue name=”best_effort_jobs”>
 <weight>0.0</weight>
</queue>

注意

如果群集的资源被队列充分利用起来,那么这些队列的作业可能需要更长时间来完成。

警告

在CDH的早期版本中有一个错误,其中值0.0将不能正常工作,单像0.01这样的值工作正常。 YARN-5077解决了该问题,位于CDH 5.7.3,CDH 5.8.2,CDH 5.9.0和更高版本中。

示例:使用maxResources保证低延迟应用程序的资源

摘要:具有运行具有特殊低延迟要求的应用程序的特殊队列。

实现:假设我们有一个具有以下资源的集群:。通过在other_jobs队列上设置maxResources属性,FairScheduler为low_latency队列留下

<queue name=”root”>
 <queue name=”low_latency” />
 <queue name=”other_jobs”>
   <maxResources>16000 gb,8000 vcores</maxResources>
 </queue>
</queue>

注意

  • 所有应用程序在other_jobs队列中的总利用率不能超过集群的80%。
  • 通过为low_latency队列留下约20%的集群资源,应用程序可以尽快启动
  • 这种情况仅作为示例提供。在许多情况下,最好使用下面的“使用抢占的低延迟应用队列”例子。

示例: 使用抢占来保证资源到低延迟应用程序,而不损害利用率

摘要:运行具有低延迟要求的应用程序的队列。

实现:假设我们有一个具有以下资源的集群:。此配置将在low_latency队列上启用抢占。

<queue name=”root”>
 <queue name=”low_latency”>
   <fairSharePreemptionThreshold>1.0</fairSharePreemptionThreshold>
   <fairSharePreemptionTimeout>1</fairSharePreemptionTimeout>
 </queue>
 <queue name=”other_jobs”>
 </queue>
</queue>

注意

  • 与maxResources版本(参见上一个示例)不同,整个集群资源可用于other_jobs队列,但是又可以抢占other_jobs中的应用程序,以使low_latency队列启动应用程序运行。
  • 如果您仍希望限制low_latency队列的总集群使用率,可以应用maxResources。
  • 稍后还有两个优先级队列的示例显示如何以更复杂的方式使用抢占。
  • 提醒:要在FairScheduler中启用抢占,必须在yarn-site.xml中设置此属性:


    yarn.scheduler.fair.preemption
    true

示例:限制Ad-Hoc队列的大小

摘要:允许子ad-hoc队列具有maxResources设置

实现:通常,不能在ad-hoc队列上设置属性,因为它们没有在fair-scheduler.xml文件中定义。通过在some_parent队列上设置maxChildResources属性,该队列的任何子项(例如ad-hoc用户队列或ad-hoc组队列)将等效于 8192 mb,8 vcores </ maxResources>设置。

<queue name=”some_parent”>
  <maxChildResources>8192 mb,8 vcores</maxChildResources>
</queue>

注意

此功能是在CDH 5.9.0中引入的新功能。

示例:组织队列

摘要:为每个组织提供其应用程序的队列。

实现:为每个组织提供一个队列,在这种情况下是sales, marketing, finance, 和 data science。每个团体获得相等份额的Steady FairShare。

<queue name=”root”>
<queue name=”sales” />
<queue name=”marketing” />
<queue name=”data_science” />
</queue>

分层实现:sales组织有northamerica和europe子队列。marketing组织有reports和website队列。 data_science组织具有prioritybest_effort队列。

<queue name=”root”>
<queue name=”sales”>
  <queue name=”northamerica” />
  <queue name=”europe” />
  <queue name=”asia” />
</queue>
<queue name=”marketing”>
  <queue name=”reports” />
  <queue name=”website” />
</queue>
<queue name=”data_science”>
  <queue name=”priority”>
    <weight>100.0</weight>
  </queue>
  <queue name=”best_effort”>
    <weight>0.0</weight>
  </queue>
</queue>
</queue>

示例:严格优先级队列

摘要:这是一个优先级队列的替代方法。

实现:在前面的示例中,FairScheduler使用抢占来强制执行100/10/1的容器分配。在此版本中,root.other和root.other.other队列的权重为0.这具有以下效果:

1.priority1队列中的任何作业将首先完全分配,然后将任何备用资源分配给priority2队列中的作业。最后,之后的任何备用资源将被给予priority3队列
2.如果每个优先级队列都有超出集群容量的作业,则priority2队列中的作业将仅在priority1中所有作业的总资源需求低于集群容量后开始。对于priority2队列中的作业,优先级高于priority3队列中的作业也是如此。
3.如果将作业添加到priority1队列,那么当任务从队列priority2和priority3完成时,容器将分配给这些新作业。类似地,如果将新作业添加到priority2队列(并且假设priority1作业保持完全分配),那么当priority3队列中任务完成时,这些作业将获得容器。

<queue name=”root”>
 <queue name=”priority1”>
 </queue>
 <queue name=”other”>
   <weight>0</weight>
   <queue name=”priority2”>
   </queue>
   <queue name=”other”>
     <weight>0</weight>
     <queue name=”priority3”>
     </queue>
   </queue>
 </queue>
</queue>

注意

  • 如果在所有队列上启用抢占,则添加到priority1队列中的任何作业将立即抢占priority2和priority3中的作业。类似地,priority2队列中的任何添加的作业将优先于priority3队列中的作业。
  • 可以根据需要添加许多级别的层次结构,以满足您的需求。
  • 如前面“Best Effort队列”示例中所述,在CDH的早期版本中存在一个错误,其中值0.0将不能正常工作,但真正微小的值(例如0.01)工作正常。

示例:使用抢占实现优先级

摘要:给定以下情况:(a)以容量运行的群集,以及(b)其分配低于其FairShare的“高优先级”队列。打开抢占保证资源在提供的超时值内可用。

实现:必须在FairScheduler中启用抢占,方法是在yarn-site.xml中设置以下属性:

<property>
 <name>yarn.scheduler.fair.preemption</name>
 <value>true</value>
</property>

下面是fair-scheduler.xml中的队列示例。如果队列在60秒内未收到其FairShare的80%,FairScheduler将开始从some_other_queue抢占应用程序并将资源提供给priority_queue

<queue name=”priority_queue”>
  <weight>75.0</weight>
  <fairSharePreemptionThreshold>0.8</fairSharePreemptionThreshold>
  <fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
</queue>
<queue name=”some_other_queue”>
  <weight>25.0</weight>
</queue>

示例:抢占资源更多级别的优先级

摘要:当两个优先级级别不足以分隔作业优先级需求时,您可以使用三个级别的优先级和抢占。

实现high_prioritymedium_priority队列启用抢占。 low_priority队列不会启用抢占。为了防止medium_priority队列从high_priority队列抢占容器,我们还将在high_priority上设置allowPreemptionFrom属性。

<queue name=”root”>
 <queue name=”high_priority”>
   <weight>100.0</weight>
   <fairSharePreemptionThreshold>0.9</fairSharePreemptionThreshold>
   <fairSharePreemptionTimeout>120</fairSharePreemptionTimeout>
   <allowPreemptionFrom>false</allowPreemptionFrom>
 </queue>
 <queue name=”medium_priority”>
   <weight>10.0</weight>
   <fairSharePreemptionThreshold>0.5</fairSharePreemptionThreshold>
   <fairSharePreemptionTimeout>600</fairSharePreemptionTimeout>
 </queue>
 <queue name=”low_priority”>
   <weight>1.0</weight>
 </queue>
</queue>

注意:allowPreemptionFrom属性,在CDH 5.7.0中才引入。

为Oozie启动器作业设置单独的队列

摘要:当Oozie启动某个操作时,启动器作业需要使用一个MapReduce应用程序主文件与一个任务实际启动该作业。在Oozie同时启动许多操作的情况下,队列和或群集可能会使用Oozie Launcher MapReduce AM命中maxAMShare,这将导致死锁,因为任何随后的YARN应用程序无法启动AM

解决方案是将Oozie启动器作业放入单独的队列,并根据需要限制队列。

示例

在您的Oozie工作流中,将属性oozie.launcher.mapred.job.queue.name设置为指向Oozie启动器队列:

<property>
      <name>oozie.launcher.mapred.job.queue.name</name>
      <value>launcher</value>
</property>

在FairScheduler中,为启动器作业创建队列

<queue name=”launcher”>
 <maxRunningApps>10</maxRunningApps>
</queue>

注意

  • 这不是FairScheduler的具体问题。然而,Oozie和YARN之间的这种相互作用是一个很常见的问题,这个问题在小集群上尤其常见。
  • 将诸如maxResources或maxRunningApps之类的限制放在启动器队列上将有助于防止Oozie启动器作业对群集进行死锁。

在根或父队列上进行硬限制

摘要:在FairScheduler中,硬限制(如maxRunningApps或maxResources)自上而下传播。同样,在根队列上设置这样的属性将影响所有队列。

示例:root.parent1的maxRunningApps设置为1.因此,尽管在childA和childB队列中将maxRunningApps设置为大于1的值,但只能运行一个应用程序。

<allocations>
 <queue name="root">
   <queue name="parent1">
    <maxRunningApps>1</maxRunningApps>
     <queue name="childA">
       <maxRunningApps>3</maxRunningApps>
     </queue>
     <queue name="childB">
       <maxRunningApps>3</maxRunningApps>
     </queue>
   </queue>
 </queue>
</allocations>

删除队列

摘要:没有直接的方法可以通过命令行或UI删除队列。但是,如果更新fair-scheduler.xml配置文件并删除文件中的队列,则在下一个调度程序配置刷新时,将删除队列。

解决方案:确保队列中的所有应用程序在实际更改配置之前具有状态FINISHED。在MR应用程序的情况下,还要确保它们保存在JobHistoryServer中。

FairScheduler抢占是全局的

摘要:FairScheduler中的抢占是全局性的。调度器查看高于其FairShare的所有队列,并去获取这些资源,将它们分配到低于它们的FairShare的队列。目前没有将抢占限制到队列子集的形式,或者只允许从queueA到queueB的抢占。

解决方案:allowPreemptionFrom属性用来控制是否允许抢占。未来版本的FairScheduler可能允许其他形式的控制或分组。

小群集但是有大量job

摘要:用户运行小型集群并不罕见,其中活动队列数(带有作业)与集群中的资源量(vcores或GB)相配。这可能发生在测试群集中。在小型群集中当太多的大作业提交到同一队列时,livelock的情况或者执行相当缓慢。

解决方案:考虑限制小型集群上的队列数。此外,还可以通过设置maxRunningApps属性来限制队列中正在运行的作业数。例如:

<queue name=”big_jobs”>
 <maxRunningApps>5</maxRunningApps>
</queue>

扩展阅读

要获得有关Fair Scheduler的更多信息,请查看在线文档(Apache HadoopCloudera CDH 5.9.x

致谢

感谢Andre Araujo,Paul Battaglia,Stephanie Bodoff,Haibo Chen,Spandan Dutta,Yufei Gu,Jonathan Hsieh,Patrick Hunt,Adrian Kalaszi,Karthik Kambatla,Robert Kanter,Justin Kestelyn,Vijay Kalluru,Cris Morris,Sandy Ryza,Grant Sohn, Wilfred Spiegelenburg,Juan Yu和Zhang Yongjun Zhang对这个系列文章的评论。

Ray Chiang是Cloudera的软件工程师。

Dennis Dawson是Cloudera的高级技术撰稿人。

原文地址Untangling Apache Hadoop YARN, Part 5: Using FairScheduler queue properties

打赏支持:支付宝/微信,感谢赏口饭吃