在spark数据帧联合中,联合后内存中的父数据帧会发生什么?如果存在内存或CPU占用空间,如何执行垃圾回收?
val childDf = parentDf1.union(parentDf2)
联合是否会导致缓存或保留在父数据帧上?
是
parentDf1.unpersist(true)
有效果吗?
由于spark的评估比较懒惰,因此可以推断,如果我从不引用父df的parentDf1 parentDf2,则它们将不会被缓存或保留。
合并后,父数据帧是否对内存或CPU有其他影响?
我可以确保使用完parentDf1和parentDf2之后没有任何痕迹吗?
答案 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()方法,但要在正确的代码位置。