在之前的第 4 部分中,我们描述了 Apache Hadoop 中最常用的 FairScheduler 属性。在第 5 部分中,我们将提供一些示例来展示如何单独或组合使用属性来实现常见的期望行为,例如应用程序优先级排序和组织队列
场景 Best Effort Queue
描述:在公平调度器中,当一个队列的权重(weight)等于0.0的时候,代表这个队列当集群资源存在空闲的时候他才能运行app,换句话说,所有在priority_jobs队列的app会优先的获取分配,剩余的空闲的资源才会分配给best_effort_jobs队列
<queue name=”priority_jobs”>
</queue>
<queue name=”best_effort_jobs”>
<weight>0.0</weight>
</queue>
提示:
如果集群被其他队列中运行的作业充分利用,集群中的作业可能需要很长时间才能完成。
警告:CDH的早期版本中存在一个bug,其中值0.0不能正常工作,但是非常小的值(例如0.01)可以正常工作。YARN-5077 修复了该问题,并在CDH 5.7.3、CDH 5.8.2、CDH 5.9.0及更高版本中发布
场景:使用maxResources去保证低延迟应用的资源
描述:假如我们需要一个队列去运行低延迟应用,我们假设集群有资源<memory:2000gb,vcores:10000>,我们为other_jobs设置maxResources,公平调度器将会为low_latency队列留出<memory:4000 gb, vcores:2000>的资源
摘要:有一个特殊队列,用于运行具有特殊低延迟要求的应用程序。
实现:假设我们有一个具有以下资源的集群:<memory:20000 gb,vcores:10000>。通过在other_jobs
作业队列上设置maxResources属性,FairScheduler为low_latency
队列保留<memory:4000 gb,vcores:2000>。
<queue name=”root”>
<queue name=”low_latency” />
<queue name=”other_jobs”>
<maxResources>16000 gb,8000 vcores</maxResources>
</queue>
</queue>
提示:
other_jobs
队列中的所有应用程序的总利用率不能超过群集的80%。
通过将大约20%的集群留给低延迟队列,那里的应用程序可以尽快启动。
本案例仅作为示例提供。在许多情况下,最好使用下面的“使用抢占的低延迟应用程序队列”。
场景:通过抢占去保证低延应用的资源使用
摘要:有一个特殊队列,用于运行具有特殊低延迟要求的应用程序。
实现:假设我们有一个具有以下资源的集群:<memory:20000 gb,vcores:10000>。此配置打开低延迟队列上的抢占。
<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中设置此属性
<property>
<name>yarn.scheduler.fair.preemption</name>
<value>true</value>
</property>
场景: 限制 Ad-Hoc 队列资源使用
摘要:允许子Ad-Hoc队列具有maxResources设置
实现:通常情况下,不可能在 ad-hoc 队列上设置属性,因为它们没有在fair-scheduler.xml文件中定义。通过在some_parent
父队列上设置maxChildResources属性,该队列的任何子队列(例如,ad-hoc user queues或ad-hoc group queues)将具有相当于<maxResources>8192 mb、8个vcores</maxResources>的设置。
<queue name=” some_parent ”>
<maxChildResources>8192 mb,8 vcores</maxChildResources>
</queue>
提示:
This feature was introduced in and is new to CDH 5.9.0.
场景:为每个部门的应用分配资源队列
描述:为每个部门分配队列,在这个例子中,sales,marking,finance和data science每个部门都有相同的Steady FairShare值
<queue name="root">
<queue name="sales"/>
<queue name="marketing"/>
<queue name="data_science"/>
</queue>
除此之外,在sales队列里面还有northamerica和europe的子部门,
data_science
拥有priority
和best_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。这将产生以下后果:
priority1
队列中的任何作业都将首先fully allocated,然后将所有空闲资源分配给priority2
队列中的作业。最后,之后的所有空闲资源都将分配给priority3
队列。
如果每个优先级队列的作业超出了群集的容量,则只有在priority1
中所有作业的总资源需求低于群集的容量后,priority2
队列中的作业才会开始。priority2
队列中的作业在priority3
队列中的作业之前分配也是如此。
如果将作业添加到priority1
队列中,则当任务从队列priority2
和priority3
完成时,容器将分配给这些新作业。类似地,如果将新作业添加到priority2队列(并假设priority1
作业保持fully allocated),则当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 Queue”示例中所提到的,CDH的早期版本中存在一个bug,其中值0.0不能正常工作,但是非常小的值(例如0.01)可以正常工作。
场景:使用抢占实现队列优先级
小结:考虑到以下情况:(a)一个集群正在满负荷运行,(b)一个“high priority”队列,其分配低于其FairShare。启用抢占可以保证资源在提供的超时值内可用。
实现:必须通过在Thread-site.xml中设置此属性在FairScheduler中启用抢占:
<property>
<name>yarn.scheduler.fair.preemption</name>
<value>true</value>
</property>
下面是fair-scheduler.xml中的队列示例。如果队列在60秒内未收到其80%的FairShare,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_priority
和medium_priority
队列已启用抢占。low_priority
队列将不会启用抢占。为了防止medium_priority
队列抢占high_priority
队列中的容器,我们还将在high_priority
上设置AllowPremptionFrom
属性。
<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>
提示: Notice this uses the new allowPreemptionFrom property, introduced in CDH 5.7.0.
场景:在根队列或父队列上设置硬限制
摘要:在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配置文件并删除文件中的队列,则在下一次scheduler configuration refresh时,该队列将被删除。
解决方案:在实际更改配置之前,确保队列中的所有应用程序的状态都已完成。对于MR应用程序,还要确保它们保存在JobHistoryServer中。
FairScheduler抢占是全局的
概要:FairScheduler中的抢占是全局的。调度程序查看所有大于FairShare的队列,获取这些资源,并将它们分配到低于FairShare的队列。目前没有将抢占限制到队列子集或只允许从queueA
抢占到queueB
的形式。
解决方案:AllowPremptionFrom
属性允许某种有限版本的抢占控制。FairScheduler的未来版本可能允许其他形式的控制或分组。
Gotcha: Small Clusters and/or lots of Really Large Jobs
摘要:用户运行small clusters的情况并不少见,其中 active queues(with jobs)的数量与集群中的资源量(vCore或GBs)相当。这可能发生在testing/staging 集群中。当太多的 large job提交到同一队列时,也会出现类似的情况。在这些情况下,集群可能会进入livelock,或者作业可能非常慢。
解决方案:考虑限制小型集群的队列数。此外,考虑通过设置Max RunIsApp属性来限制队列中运行的作业的数量。例如:
<queue name=”big_jobs”>
<maxRunningApps>5</maxRunningApps>
</queue>
网友评论