从内存中触发未缓存的RDD收回

时间:2019-04-28 10:06:54

标签: scala apache-spark

根据这篇帖子How long does RDD remain in memory?,基于以下几点,我想知道:

  

RDD是一个与其他对象一样的对象。如果您不坚持/缓存   它将充当托管语言下的任何其他对象,并且   一旦没有活着的根对象指向它,该被收集吗?

一旦没有活动的根对象指向它,到底是什么意思?

  • 例如该动作何时完成?
  • 或者是否成功执行了转换?

我读了尽可能多的书,但发现我脑子里总有一个未解决的问题。这位知名专家的回应让我心存疑虑,我无法驱逐。

When does a RDD lineage is created? How to find lineage graph?示例很好,在此处重新显示:

val nums = sc.parallelize(0 to 9)
scala> nums.toDebugString
res0: String = (8) ParallelCollectionRDD[0] at parallelize at <console>:24 []

val doubles = nums.map(_ * 2)
scala> doubles.toDebugString
res1: String =
(8) MapPartitionsRDD[1] at map at <console>:25 []
 |  ParallelCollectionRDD[0] at parallelize at <console>:24 []

val groups = doubles.groupBy(_ < 10)
scala> groups.toDebugString
res2: String =
(8) ShuffledRDD[3] at groupBy at <console>:25 []
 +-(8) MapPartitionsRDD[2] at groupBy at <console>:25 []
    |  MapPartitionsRDD[1] at map at <console>:25 []
    |  ParallelCollectionRDD[0] at parallelize at <console>:24 []

假设每个转换都需要很长时间才能实际执行,那么何时可以驱除RDD [0]?即最早的时间点。关键是... RDD [0]是... RDD [1..N]的父对象还是所有此类对象的父对象?我在其他地方找到这样的声明时说。

我不认为它是重复的,它正在寻求澄清所陈述的内容。

我的解释是,术语“根对象”意味着RDD [0]不能进行垃圾回收,直到发生某个Action或Action DAG路径中的缓存或检查点发生为止。寻求验证。对于我来说关于根对象是什么的句子现在还不清楚。我本以为根对象是链中较早的RDD。

1 个答案:

答案 0 :(得分:4)

RDD具有不同类型的内存足迹:

1)它消耗驱动程序上的内存(作为常规对象)

2)有关该RDD的信息已分配给工作人员

3)如果缓存了RDD,它可能会在worker上分配额外的空间

当根据(1)无法访问RDD时,将通过ContextCleaner触发对(2)和(3)的清除。 所以我们只在谈论(1)。

RDD是否已缓存完全无关紧要。执行count / collect之类的动作也没有关系。 当您离开该RDD可见的范围时,RDD只是作为常规的Java对象而消失。

在您的特定示例中,RDD1取决于RDD0,因此除非前者被驱逐,否则后者将不会被驱逐。并且RDD1仅在RDD2之后被驱逐,而RDD3之后将被驱逐。要为垃圾收集器解锁RDD3,您必须(隐约地说)将方法保留在使用它的位置。