在Spark数据帧联合中,联合后内存中的父数据帧会发生什么变化?

时间:2019-04-21 09:38:51

标签: apache-spark apache-spark-sql

在spark数据帧联合中,联合后内存中的父数据帧会发生什么?如果存在内存或CPU占用空间,如何执行垃圾回收?

val childDf = parentDf1.union(parentDf2)

联合是否会导致缓存或保留在父数据帧上?

parentDf1.unpersist(true)

有效果吗?

由于spark的评估比较懒惰,因此可以推断,如果我从不引用父df的parentDf1 parentDf2,则它们将不会被缓存或保留。

合并后,父数据帧是否对内存或CPU有其他影响?

我可以确保使用完parentDf1和parentDf2之后没有任何痕迹吗?

1 个答案:

答案 0 :(得分:1)

在功能上,您不需要对RDD或父RDD执行任何操作,因为不再需要它们时-它们将-作为Java对象-垃圾收集。 Spark中为对象ContextCleaner分配了此角色。

如果Spark应用终止或这些RDD所基于的操作已完成,则ContextCleaner会清理它们,或者您可以使用unpersist操作明确地执行此操作,如您所暗示。我不相信自己会打扰,因为需要小心;我还阅读了有关一些副作用的博客:https://medium.com/lookout-engineering/apache-spark-pitfalls-rdd-unpersist-568f9350fe1d

  

引用其他地方的内容:RDD与其他任何对象一样都是对象。如果   您不保留/缓存它,它会充当   一旦没有活着的根,就将收集托管语言   指向它的对象。

这意味着如果您通过映射拥有rdd1-> rdd2-> rdd3,则当应用于rdd3的操作结束或作业崩溃且无法恢复时,这是向ContextCleaner发出的信号-每当它下次解决它-从rdd3开始垃圾收集分区和RDD,然后向后工作。例如。如果rdd3尚未被驱逐,则rdd2无法驱逐。

那么,在您的情况下:父数据帧可能没有在“缓存”中徘徊,即使它们没有被明确地缓存/持久化,因为Spark需要存储中间结果作为计算等结果,以便通过DAG,bla, bla,bla。

此外,Spark Context Cleaner监视缓存使用情况,每个节点上数据管道中使用的存储,并以最近最少使用(LRU)的方式丢弃旧数据分区,无论是否进行显式缓存。

如果要手动删除一个RDD而不是等待通过ContextCleaner决定删除它,可以使用RDD.unpersist()方法,但要在正确的代码位置。