Spark清理shuffle溢出到磁盘

时间:2016-01-14 11:30:33

标签: scala apache-spark out-of-memory spark-streaming

我有一个循环操作,它生成一些RDD,重新分区,然后是aggregatebykey操作。在循环运行之后,它计算最终的RDD,它被缓存并检查点,并且还用作下一个循环的初始RDD。

这些RDD非常大并且在每次迭代到达最终RDD之前会生成大量中间混洗块。我正在压缩我的shuffle并允许shuffle溢出到磁盘。

我注意到我的工作机器上没有清理存储随机文件的工作目录。因此最终我的磁盘空间不足。我的印象是,如果我检查我的RDD,它将删除所有中间shuffle块。然而,这似乎没有发生。任何人都有任何关于如何在循环的每次迭代后清理我的shuffle块的想法,或者为什么我的shuffle块没有被清理?

2 个答案:

答案 0 :(得分:1)

将RDD缓存到内存/磁盘后,只要spark上下文处于活动状态,RDD就会存储在内存/磁盘中。

为了告诉驱动程序它可以从内存/磁盘中删除RDD,您需要使用unpersist()功能。

  

来自java-doc

 /**
   * Mark the RDD as non-persistent, and remove all blocks for it from memory and disk.
   *
   * @param blocking Whether to block until all blocks are deleted.
   * @return This RDD.
   */
  def unpersist(blocking: Boolean = true)

所以你可以使用:

rdd.unpersist()

答案 1 :(得分:1)

取决于您是否在这些RDD之间存在依赖关系。例如:

val rdd2 = rdd1.<transformation>
val rdd3 = rdd2.<transformation>
...

这种情况下,火花将记住血统,并且将始终存在对旧RDD的引用,这使得它不被火花驱动器清理(火花驱动器上的gc火花rdd清理被gc放下来回收一旦他们不再被引用,一些rdd引用。) 所以persist()在这种情况下不会工作,唯一的方法是使用localCheckpoint()。这就是我以前做过的,并为我工作过:

rdd.persist(StorageLevel.MEMORY_AND_DISK_2)
          .localCheckpoint()
// do sth here and later
rdd.unpersist()

这使得火花正确地截断了血统,然后你可以安全地unpersist()它而不用担心未清洁的参考。
请参阅spark doc,了解如何正确截断执行计划沿袭:https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-rdd-checkpointing.html