OSDI作为计算机系统类的顶会,其中发表的论文的研究方向基本是计算机研究类的风向标,当前最受关注的。而本届OSDI中有四篇关于资源调度方面的文献(Cloud Systems Part),可以看出当前关于资源调度仍然是研究的重点。
写这篇博客的目的是想以通俗易懂的方式交流调度,由于才疏学浅,文中理解错误之处欢迎指正以及批评拍砖。
本篇文章通过一种利他和延迟调度策略,对任务进行调度。调度面向的是长期任务调度,能够满足多维度的度量需求,如公平性、资源利用率、任务平均完成时间。
文章通过一个具体的例子进行讲解。
场景:
如图所示,当前存在两个任务,Job1和Job2,Job1内部存在三个子任务S0,S1,S2,Job2只有S0。对于每个任务,该任务所需要的资源在下方显示。如S0,执行该任务需要0.29个单位的资源,需要用时1个单位。
目标 :
对这两个任务进行调度,使得资源利用率高,平均任务完成时间短。
在文章中,作者发现,在现有的调度系统中,主要存在如下的一些特点:
* 现有的调度系统关注瞬时公平性(instantaneous fairness)以及短期优化(short-term
optimizations)
* 现在的长任务给了调度更多的灵活性
* 数据并行类的作业对于长作业优化提供了更多机会
在任务的调度过程中,主要有两个维度的调度。第一是任务间的调度,即job1和job2 之间的调度。第二类是任务内的调度,比如job1中存在S0,S1,S2这三个任务,调度的目标就是这三个子任务。
那什么是保证瞬时公平性和短期优化的调度方法呢?
首先假设我们知道所有的任务,它的运行时间,以及其对于资源需求多少。那对于公平性的保证,首先对资源进行平分,假如资源总量为1,现在有两个任务,那一个任务就分配0.5.这样就保证了公平性。这样的调度是**任务间的调度**。
在分配了资源以后,任务拿到了分配的资源,就需要充分利用自己手里的资源,也就是需要进行任务内部的调度。这样就是**任务内的调度**。内部调度可以采用贪心策略,使得任务安排的紧紧的。这样就可以使得资源利用率提高。经过这种调度方案的调度后效果如图所示:
从当前的调度策略看,既保证了公平性,保证资源隔离,同时也照顾到了资源利用率。那么问题来了。这样的调度就很好吗?那我们能继续优化吗?当然可以,这也就是这篇论文的贡献点。
从上述的瞬时公平性和短期优化的调度方法还是存在问题的。从图中可以看到,这种调度方法并不是最好的,每个资源内部还存在很多空闲没有使用的资源。这里作者提出了一个很重要的一个观念
用户并不关心瞬时的调度效果,关心的是整个作业的完成时间。
那也就说,只要保证任务的总体完成时间不增长,那么我就可以在任务原来完成时间之前随意调度子任务,使得资源利用率提供,或者减少JCT(Job Completion time)。这样也就多出了很多操作的可能性(前面提到的第二个特点)。
综上所述。基于用户只关心JCT(JCT短,资源利用率也不会差),那咱们就在基本JCT之前调度任务,尽量提高资源利用率以及任务平均的完成时间。
本文可以做到这样的效果:
通过现有的调度策略,会有一个任务的完成时间。如何在保证任务完成时间不会增长的情况下,提出一个新得调度方案,使得减少平均任务完成时间,提高资源利用率,同时也能兼顾公平性等特性?
提出了问题,那么如何去解决呢?大牛分析了这个问题能不能解决,有没有解决的可能性。(答案当然是肯定的,否则这篇文章怎么撸出来的)
- 首先,当前的主要任务,多是复杂的DAG结构,任务中存在很多关联关系。所有是存在很多调度对象的。此外,任务的DAG图越来越长,使得调度的空间也越来越多。
- 根据数据显示,至少在20%的资源,有存在50%的时间没有用满,存在剩余资源。
从上面的两条结论,可以看出还是很有可能,解决提出的问题的,因为可操作的空间很大。
那我们就来解决一下。
当当当,文章的精华来了。跟着大牛们的思路去看看他们是如何解决的。他们给解决方案取了一个名字叫Carbyne(嗯……炭?)
前面说到,整体方案分为两个阶段,一个是任务间调度,一个是任务内部调度。那我们就从这两个维度出发,去解决问题。
首先我们再次明确我们需要解决的问题:
Question:如何在保证任务完成时间不会增长的情况下,提出一个新得调度方案,使得减少平均任务完成时间,提高资源利用率,同时也能兼顾公平性等特性?
可以看到我们的基本思路是尽量让资源利用率提高,尽量减少任务的完成时间。基本思路是将其他任务的剩余资源利用起来,分配给任务去使用。可以将大问题分割为三个小问题。
1.任务间调度的目标:如何最大化剩余资源的数量?
2.任务内调度的目标:剩余资源应该贡献多少给别的任务使用?
3.资源的重新分配:在获得剩余资源后,资源应该如何重新分配下去?
这三个问题解决后,解决方案也就明确了。那我们以此分别来看一下。
一.任务间调度
任务间调度,关注的是最大化剩余资源。在原来的调度方案中,瞬时的调度策略延长了任务的完成时间,虽然是延长了任务的完成时间,但是却给了我们执行利他策略的最大机会。因此在任务间调度,以前的调度策略都可以,较长的任务完成时间也无所谓,刚好可以给我增加调度的可操作性。
因此任务间调度只需要保证公平性就行。Carbyne在任务间调度采用的是DRF,因为这个是在公平性中做的很好的。当然任意其他的公平性调度策略都可以,只要公平地把资源分配下去即可。
二.任务内调度
Step1:计算剩余资源量
既然资源分配下去了,那任务内的剩余空闲资源有多少呢?那么我们在任务内调度阶段,首先要解决的是计算有多少剩余资源可以贡献给别的任务。在传统的调度方案中,是首先计算任务的期望完成时间,也就是我在知道了每个任务的完成时间后,通过计算能得出任务可能会什么时候完成。在Carbyne中,这一步也是需要的。
Step2: 延迟调度
这一步就是不一样了,集中注意力,前方高能!!如图所示,策略是在知道了任务的期望完成时间后,那就尽量晚调度,把任务从后往前排,使得后面的资源先装满。这样的策略的好处是在不延长任务完成时间的前提下,尽量把前面的资源空出来,留给别人。那别人在前期就有了很多可用资源,那他的任务完成时间就会缩短,平均任务完成时间也就短了。
那这个时候前面的资源就多出来了。这时候就通过利他策略去分配这个多出的资源了。
移动后
这一步也是Carbyne的独特之处,同样高能!。在这一步我们要做的事情是,通过上一步的延迟调度,我们得到了一些新的空闲资源。那我们怎样去重新分配这个空闲资源给别的任务,让别的任务早点完成,从而降低任务的平均完成时间呢?
首先我们再次明确一下在这个阶段,我们需要达到的目标:
* 减少任务平均完成时间
* 最大化资源利用率
当然这两个目标其实可能有关联,任务完成时间少了,资源的利用率可能就会很高。目标明确了,那我们怎么去实现这两个目标呢?
对于第一点,作者的策略是:先执行所需完成时间最短的任务。这样就会有任务会减少他的完成时间,那平均完成时间就少了。调度后效果如图:
对于第二点,作者的策略是:尽可能把没有调度的任务打包执行(Pack as many unscheduled tasks are possible)。这一点我不是很理解,反正达到的效果是如图这样:
从上面的三个步骤,我们分别实现了:1.通过公平调度策略,提高了资源的剩余量。2。通过任务内部调度,计算出了可以用于贡献的剩余资源。3.通过利他调度策略,提高了资源利用率,降低了平均任务完成时间。
这样,最开始的问题就解决了…决了……了……最后的实验验证部分就不再讨论了,有兴趣的可以去下载这篇论文
鉴于本渣能力有限,很多理解不清楚或者不正确的地方,欢迎指出