abstract
spark没有一种智能化挑选合适的RDD的机制去将RDD缓存。提出了一种细粒度的RDD检查点机制和选取RDD的策略从而增强内存使用率。文中根据RDD的宽窄依赖选取RDD,将后期重用较多的RDD优先缓存。
introduction
当RDD的某个分区丢失或者失败可以通过血缘(lineage)关系重建。但是对于长时间迭代型应用来说,随着迭代的进行,RDDs之间的血缘关系会越来越长,一旦在后续迭代过程中出错,则需要通过非常长的血缘关系去重建,势必影响性能。为了克服这个问题,出现了检查点(checkpoint)。RDD支持checkpoint将数据保存到持久化的存储中,这样就可以切断之前的血缘关系,因为checkpoint后的RDD不需要知道它的父RDDs了,它可以从checkpoint处拿到数据。是否将RDD设为检查点大多取决于经验,对于复杂的应用来说提供一个好的设计方法较为困难。将重用较少的中间结果缓存将会浪费存储空间降低性能。
另一方面,当内存资源耗尽时,spark会选取最近未使用的RDD,将其从内存中踢出,其中选取算法用的是LRU。这种算法只考虑到分区最近是否被使用过,却没有考虑这个分区的重要性(针对宽窄依赖,以后会使用的次数)。例如剔除了一个宽依赖的RDD,再次使用它时就要再次计算出它,若剔除一个窄依赖的,再次使用的几率会少一些。或者,剔除的是在血统上较早的一个RDD,那么在以后使用它时,计算的代价较大。
针对上述问题,(1)提出了一种细粒度的检查点技术避免丢弃会经常使用的RDD(对应下面的1)
检查点是在计算完成后重新建立一个job来计算,先将RDD缓存这样保证检查点操作快速完成。(文中不是 优化这个)
(2)设计了一种对长血统宽依赖的RDD优先缓存的方法(对应3)
intelligent RDD management
1.细粒度检查点
spark提供了一种粗粒度的检查点方法,将检查点之前的RDD全部抛弃。这个机制可以避免重复计算检查点RDD,切断血缘关系。但会严重的降低性能。因为以后壳能会用到被抛弃的RDD。这时就要从其他RDD收集计算这个RDD的信息进行重新计算。细粒度的检查点方法不会直接抛弃所有的先祖RDD,而是针对全局考虑被抛弃的RDD。所有的剔除RDD的方法是3.(未被抛弃的RDD,怎么让新的job知道与job自己的关系呢?这个新的job不知道关系,但是其他的jobx知道这个关系啊,要是删除了所有RDD,若某个RDD与jobx与有关,jobx中存储了这个RDD的血统,需要重新计算。)
2.选择血统还是检查点
为了切断长血统(long lineage chains),避免出现问题时花费很多时间经由这个很长的血统重新计算RDD,就会checkpoint一些RDDs。
将RDD设位检查点的条件: L>=C*(1-w) L从血统中计算的时长,C重检查点计算的时长,w失败频率
若满足此条件则将其设为检查点。
(a. 在实际运用中怎么知道L,C,w的值? b. 这个式子时永远满足吗? 不是永远满足,从检查点计算也需要考虑到其他线程中的计算情况,要考虑恢复因建立检查点被丢弃的RDD的计算时间。)
3.剔除机制
针对有限的内存空间,spartk使用了LRU算法,剔除RDD。这里提出了另一种剔除RDD的方法,给RDD加一个优先级,剔除低优先级的(P)。