首先,介绍前辈研究的基于MapReduce框架的outlier产生原因;其次,根据这些方面来分析Spark架构中的straggler;最后,根据阅览的优化办法,谈谈自己的看法。

一、MapReduce产生outlier的原因

  outlier是指MapReduce中延长job执行时间的因素,参考文献为Reining in the Outliers inMap-Reduce Clusters using Mantri

  MapReduce整体系统产生outlier的原因可以分为三类:

  1、硬件特性

  静态:硬件可靠性。

  动态:资源竞争,包括进程、内存及网络等硬件资源。

  2、网络特性

  网络直接影响数据传输率,而数据中心的瓶颈原因就与数据传输率有重要关系。

  3、MapReduce特性

  分布式系统必然存在分布式的数据和分布式的任务,那么就会存在调度规则。MapReduce将job分为task,资源的调度和任务的调度都会导致task工作量的不平衡或者节点负载的不平衡。

  因此,这三个大类整体上即5个问题:资源的竞争、硬件的可靠性(主要指磁盘可靠性)、网络带宽的差异性、网络堵塞、task之间工作量的不平衡或者节点之间任务量的不平衡。这5个问题是产生outlier的根本原因。文章中也详细分析了各类问题的解法,为了深入的学习,先谈谈自己的想法,再对比文献中的解决办法。

二、Spark中的straggler

  Spark中的straggler产生的原因自然也离不开上述5个方面,但是,资源的竞争和硬件的可靠性这类硬件特性所带来的straggler是无法在执行上进行优化的,因为这类因素主要关乎系统的硬件配置;网络堵塞和网络带宽也是几乎属于不可避免的因素,这类因素导致的straggler只能依靠网络负载和网络配置的优化来解决。而且,从另一方面考虑,在系统配置和网络负载都正常的情况下,这类因素都不会产生straggler,所以这两类因素都不是对straggler的执行策略进行优化时需要考虑的。如果考虑到straggler的判定优化,可以根据网络的负载而动态配置判定方式,这不失为一种好的想法。综上所述,在对straggler的执行进行优化时主要考虑的对象是Spark框架特性所产生的straggler。

  为了便于细致的分析Spark流程中产生straggler的原因,本文使用如下的简图(本人学习阶段,可能存在问题):

  当Job被划分为框架的处理单位——task时,会产生第一个不平衡,因为每个task的任务量并不是完全对等的。每个task都会经过slave来执行,如果某个task工作量大于平均值太多,整个job的完成时间就会被延长,这个task就成为了straggler。这类straggler产生的具体原因是,straggler需求的资源比其他task要多,在分成input splits时明显多于其他的task。input splits的增多首先是map耗时变长,更为重要的是在shuffle阶段,Partition操作产生的bucket数量将使得hashmaps不能够完全存放在内存,这样就必须存放到磁盘中,而且还会导致内存使用的尴尬。所以最主要的延长原因是shuffle阶段产生的hashmaps数量过多会溢出到磁盘从而增加IO操作。

  依靠推测执行解决这个问题必然是可以减少task的按时执行对系统带来的负面影响,但是要更进一步的进行优化就必须减少这类straggler的工作量,或者保证shuffle阶段并不会造成溢出。减少straggler的工作量本身是不现实的,因为task的划分工作是保持平衡的,而task在获取资源后进行处理才开始出现不平衡,这时已经不能再进行工作量的调整操作了。保证shuffle阶段不产生溢出可以换一种想法,就是平衡shuffle的输入与输出,因为数据量远大于内存时必然不能保证不溢出。shuffle阶段由Partition产生的bucket是一块一块的分到hashmap中去的,hashmap存储在内存中,一个hashmap由一个Reduce操作来执行。这个过程是从narrow dependences到wide dependences,再到narrow dependences。

  随后,task通过network调度到不同的slave上,并且task在slave上可能还需要利用network将所需的数据传送到本地。如果slave上分配的task任务不止一个,那么slave之间就会出现负载的不平衡。而且,已经探知的straggler或者因为其他原因执行失败的task(这也是属于一种straggler)会在多个slave上执行来提高效率。推测执行解决了slave之间负载的不平衡,因为判定某个task为straggler后在更加适合的slave上执行或者在本地优先执行该straggler可以加快straggler的执行速度。但是多个slave同时执行straggler任务必然会有slave是在做没有意义的工作,造成资源的浪费。coworker提供了一种方法,就是在已经可以并行执行后续操作的地方将后续操作交给coworker来做,这样当straggler自身和coworker同时完成任务时,整个straggler的执行时间就被缩短了。这种方法很依赖于数据的划分策略,如果数据依赖性很高,coworker的执行时间会很长,虽然不会在原来的基础上延长时间,但是性能的提高效率已经不太划算了。数据的依赖性是普遍存在的,既然执行的过程无法避免,那就要看是否能够在Partition阶段分为hashmaps时就将这种依赖性减小到最弱,然后再利用coworker就可以很明显的提高效率。

三、文献中的优化办法及拓展思考

  各类关于straggler的优化办法目前是基于Hadoop的,但是Hadoop与Spark存在很多的相似点,是切入的好方法。

  总的分析,straggler的优化一般是基于以下几点:straggler的判定方法;straggler的执行决策;straggler占用的资源。

  1、LATE(Longest Approximate Time to End)

  LATE是一种新的调度算法,首先是更新了straggler的判定方法,然后是执行决策。LATE的设计目的是推翻Hadoop的前提假设:每个节点都按照近似相同的速度执行;task至始至终都按照相同的速度执行;在其他节点有空闲时间时启动推测执行的任务是没有资源消耗的;task的得分是完全按照规定的;低分的task更有可能是straggler;同种类的task需要的资源是相同的。

  LATE在于解决Hadoop环境的异构性,而Spark处理数据是以RDD为单位,粗粒度的数据处理方式对相同的硬件应该不存在太大的差异性。LATE在进行计分时,依赖的因素还包括copy,sort和Reduce阶段,而Spark是没有sort阶段的。PS:这种计分的方式看了两遍没看懂,还得再专研一下。

  2、Coworker

  Coworker主要在于优化straggler的资源占用问题。Coworker的要点在于可以讲straggler后续的操作无关联性的移植到前面并行操作,如果是单纯的narrow dependences则显得不使用了,这也是Spark与Hadoop的不同。而且sort的存在本身就是一个依赖前一阶段输出的步骤,使用Coworker就不太适合,Spark对map的输出进行partition后放入hashmaps,再统一reduce,因此hashmaps的形成必然是等partition阶段完成后,最好的情况是hashmaps呈顺序形成,但一般不现实,所以Coworker存在一定缺陷。

  新版本的Spark会着重解决内存使用的问题,拭目以待。目前资源利用这块的优化还没有什么想法。

  3、Mantri

  Mantri更偏向于对系统中的outlier进行检测,实时的检测可以及时的对outlier采取适合的决策。Mantri的特点在于能够察觉各种各样的straggler以及资源的有效管理,即将资源单独管理,可以更灵活的解决straggler问题。Mantri针对每种察觉的straggler都采取了不同的措施,这对研究straggler的优化有很大的帮助,具体有:

  task是因为争夺资源而成为straggler,那么可以将其复制到其他的slave上运行;task在低带宽的链路中传递数据而成为straggler时,寻找最近的本地资源来避免低带宽链路,如果必须经过这条链路,应该尽量避免系统布局的热点;对于等待丢失的input来重新计算的task,这类straggler可以保持其output(非常有想法的一个点,如果可以对中间的结果进行操作,很多想法都可能实现),提高执行效率;由于工作量不平衡而造成的straggler,Mantri采取的方法是在某一个阶段对各个task按照input的大小递减的顺序进行调度,利于长task提前完成。

  Mantri中的很多想法都是非常有意义的,至少它所考虑的straggler非常全面。Mantri对Mapreduce的研究对Spark的straggler的研究有很大帮助,这里面的思想需要我去认真的总结和专研。

  4、Mesos层面

  在框架体系中常看到Spark和Hadoop都是位于Mesos之上的,所以我学习了一下Mesos的内容,觉得有一些方面印象比较深刻,所以也写出来分析一下。

  Mesos提供的接口可以让不同的框架工作在同一个系统中,类比于SDN框架可以这样说:北向接口是框架,因而北向接口具有多样性,并且其上的API是可以自由编辑的;南向接口是节点,或者说是slave、执行进程,是可以制定统一执行的标准的;东西向扩展即资源的管理和应用的编排,Mesos将资源统一管理,脱离于框架,增加了灵活性。所以我突然发现Mesos居然和SDN非常相似,这似乎是一件很有意思的事情。

  前文所提到的框架特性所产生的straggler无外乎资源的利用原因,Mesos关乎资源的方面可以从南向节点的调度、东西向资源的管理和调度上入手。如果结合Mesos上的优化和Spark框架的优化,那么整体系统的优化应该更加明显。

四、总结

  很多知识都是通过论文看来的,并不系统,而论文又很多没有看懂,所以文中的错误必然不少啊。但是,Spark的straggler的产生原因必然离不开上述几个方面,其优化的策略也无非判定、调度和资源管理,优化层面则可以向下拓展到Mesos上。