示例:具有正在Running的应用程序的集群
假设我们有一个yarn集群,其总资源<内存:800GB,vcores 200>,有两个队列:root.busy
(权重=1.0)和root.sometimes_busy
(权重3.0)。通常有四种的场景:
场景A:root.busy
队列applications序占满队列,root.sometimes_busy
队列中有少量正在运行的applications(例如10%,即<memory:80GB,vcores:20>)。很快,大量applications在相对较短的时间窗口内添加到root.sometimes_busy
的队列中。所有sometimes_busy
队列中的新应用程序都将处于挂起状态,并在root.busy
队列中container结束时变为active状态。如果root.busy
队列中的任务相当短暂,则root.sometimes_busy
队列中的应用程序将不会等待很长时间来分配容器。但是,如果root.busy
队列中的任务需要很长时间才能完成,则root.sometimes_busy
队列中的新应用程序将长时间处于挂起状态。在这两种情况下,由于root.sometimes_busy
队列中的应用程序处于活动状态,root.busy
队列中许多正在运行的应用程序将需要更长的时间才能完成。
场景B:root.busy
队列和root.sometimes_busy
队列都已满或接近满,都是活动和/或挂起的applications。在这种情况下,集群将保持充分利用。每个队列将使用其fair share,root.busy
队列中的所有应用程序的总和使用集群资源的25%,root.sometimes_busy
队列中的所有应用程序的总和使用剩余的75%。
那么,如何避免场景A呢?
一种解决方案是在root.busy
队列上设置maxResources。假设在root.busy
队列上将maxResources属性设置为集群的25%。由于maxResources是一个硬限制,root.busy
队列中的应用程序将始终限制在总数的25%。因此,在可以使用100%集群的情况下,集群利用率实际上接近35%(root.sometimes_busy
队列为10%,root.busy
队列为25%)。
场景A将有显著的改进,因为集群上有空闲资源,这些资源只能用于root.sometimes_busy
队列中的应用程序,但平均集群利用率可能较低
更多公平分享定义
-
Steady FairShare:队列的理论公平共享值。该值是根据集群大小和集群中队列的权重计算的。
-
Instantaneous FairShare:调度程序为集群中的每个队列计算的公平共享值。
该值在两个方面不同于Steady FairShare:
– 未为空队列分配任何资源。
– 该值等于所有队列达到或超过容量时的Steady FairShare。 -
Allocation:等于队列中所有正在运行的应用程序使用的资源之和。
展望未来,我们将“Instantaneous FairShare ”简称为“FairShare”
The Case for Preemption
根据这些新的定义,前面的场景可以表述如下:
情景A
root.sometimes_busy
队列的Allocations value为<memory:80GB,vcores:20>,FairShare value为<memory:600GB,vcores:150>。
root.busy
队列的Allocations value为<memory:720GB,vcores:180>,FairShare value为<memory:200GB,vcores:50>。
情景B
两个队列的Instantaneous FairShare等于其稳定公平份额。
在场景A中,您可以看到两个队列的分配和Steady FairShare之间的不平衡。当容器从root.busy
队列中释放并分配给root.sometimes_busy
的队列时,资源将缓慢返回。
通过启用抢占,公平调度程序可以杀死繁忙队列中的容器,并更快地将它们分配到root.sometimes_busy
的队列。
Configuring Fair Scheduler for Preemption
要启用抢占,请在yarn-site.xml中设置此属性:
<property>yarn.scheduler.fair.preemption</property>
<value>true</value>
然后,在FairScheduler分配文件中,可以通过fairSharePreemptionThreshold
和fairSharePreemptionTimeout
在队列上配置抢占,如下例所示。fairSharePreemptionTimeout
是队列在尝试抢占容器以从其他队列获取资源之前处于FairSharePreemptionReshold
下的秒数
<allocations>
<queue name="busy">
<weight>1.0</weight>
</queue>
<queue name="sometimes_busy">
<weight>3.0</weight>
<fairSharePreemptionThreshold>0.50</fairSharePreemptionThreshold>
<fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
</queue>
<queuePlacementPolicy>
<rule name="specified" />
<rule name=”reject” />
</queuePlacementPolicy>
</allocations>
回想一下,root.sometimes_busy
队列的FairShare是<memory:600GB,vcores:150>。这两个新属性告诉FairScheduler,root.sometimes_busy
的队列将在开始抢占之前等待60秒。如果在这段时间内,FairScheduler没有收到50%的FairShare资源,FairScheduler可以开始杀死root.busy
队列中的容器,并将它们分配到root.sometimes_busy
的队列中。
需要注意的是:
fairSharePreemptionThreshold
的值应大于0.0(设置为0.0类似于关闭抢占),但不大于1.0(因为1.0将向需要资源的队列返回所有的FairShare)。
此配置中的抢占将杀死root.busy
队列中的容器,并将它们分配到sometimes_busy
队列。
反向抢占不会发生,因为在root.busy
队列上没有设置抢占属性。
抢占不会杀死sometimes_busy
队列中应用程序A的容器,并将它们分配给sometimes_busy
队列中的应用程序B。
如果未为给定队列或其parent队列之一设置fairSharePreemptionTimeout
,并且未设置defaultFairSharePreemptionTimeout
,则即使启用了抢占,此队列也不会进行抢占。
(注意:我们不会讨论队列上的minResources
和MinsharePremptionTimeout
。目前建议使用FairShare
抢占。)
网友评论