前言
在上篇文章中,笔者刚刚阐述过Yarn队列的多优先级调度策略,不同的队列分配不同的优先级等级,这样提交到优先级高的队列上的应用能被优先被处理。但是又一个问题来了,如果我们又想在同一个队列内,对应用的优先级再次进行划分呢?而不是按照纯粹提交时间来进行先后顺序调度。答案是可行的,本文笔者来简单聊聊这个话题,也刚刚好是延续着上一篇的话题内容。
问题描述
一个根本的问题:
如何在一个队列内,支持应用任务间的优先级设置?
如果在不改动任何现有功能的前提下,其实是有变通的办法的:配置多个Yarn队列,分配不同优先级,然后提交对应应用到对应的队列。
但是显然上面提到的方法非常不灵活,而且当应用规模,种类上去之后,这种方式就会越来越凸显出它的弊端。
应用优先级策略的要求
这里我们来看看,针对同个队列内,设置优先级策略,要满足怎样的基本要求呢?
主要要求如下:
- 用户能够对它们的任务设置优先级,并且优先级同样会作用在队列的子队列内。
- 队列现有的用户限制策略,按照提交时间的调度顺序控制应该与优先级策略集成,组合,形成新的应用调度策略。策略的调度方式大体如下:
1)先按照优先级来调度应用,高优先级应用先提交运行,低优先级等待高优先级应用运行结束。这里有一个例外情况,如果用户的应用达到用户资源限制范围(后面会提到),也需要进行队列等待。
2)如果优先级相同,再按照提交时间,进行排序,提交时间早的,先提交运行。 - 应用优先级的ACL管控,防止用户对其自身应用永远设置系统最高优先级运行。
细节要点
这里主要提1个细节要点:
应用优先级设置的ACL管控,这是为了防止每个用户把自己的应用设置为系统最高优先级,这样,这个功能就完全没有任何意义了。具体地来说,这个ACL设置是指定了具体某个队列,具体的用户,所设置的队列内应用的优先级,配置如下:
yarn.scheduler.capacity.root.[queue_name].[priority].acl=user1,user2
如果上面某些用户没有被配置过,则会用到系统的一个默认优先级值(当然,不可能会是系统最高优先级这种)。还有一点需要注意,这里的优先级ACL控制会与队列ACL管控联合起作用。
应用优先级的潜在问题隐患
饥饿问题
在优先级分级调度的使用场景上,有一个经常被提到的问题:饥饿问题。高优先级应用一直存在并运行,低优先级应用永远得不到资源运行。
针对这个问题,Yarn给出的解决办法是使用user-limit的机制,针对每个用户,Yarn会对其有一个最大资源使用的限制,公式如下:
Max(queue’s configured capacity / number of active users , queue’s configured capacity * user-limit-factor.)
这里面有用户限制因子控制,每个用户在最大提交应用数以及最大使用队列资源上都会被有所限制,这样发生饥饿问题的概率就会降低很多了。
抢占问题
这里的抢占问题,指的是应用多优先级下的抢占问题,比如一个队列内一个低优先级应用在运行,而高优先级应用因为没有空闲资源而必须等待低优先级应用跑完。这个时候,我们应该如何进行资源的抢占呢?这也是一个需要讨论的问题,笔者这里就不展开讨论了。
参考资料
[1].https://issues.apache.org/jira/browse/YARN-1963. Support priorities across applications within the same queue