当 Spark 意识到不再使用 RDD 时,它会取消持久化 RDD 本身吗?
Would Spark unpersist the RDD itself when it realizes it won't be used anymore?
当我们想要多次使用它时,我们可以将 RDD 持久化到内存 and/or 磁盘中。但是,我们以后是否必须自己取消持久化,或者 Spark 是否会进行某种垃圾收集并在不再需要 RDD 时取消持久化?我注意到如果我自己调用 unpersist 函数,我的性能会变慢。
是的,Apache Spark 会在 RDD 被垃圾回收时取消持久化。
在RDD.persist
中可以看到:
sc.cleaner.foreach(_.registerRDDForCleanup(this))
当 RDD 被垃圾回收时,这会在导致 ContextCleaner.doCleanupRDD
的 ReferenceQueue 中放置对 RDD 的弱引用。还有:
sc.unpersistRDD(rddId, blocking)
有关更多上下文,请参阅一般的 ContextCleaner 和添加它的 commit。
非持久化 RDD 依赖垃圾回收时需要注意的几点:
- RDD 使用执行器上的资源,而垃圾回收发生在驱动器上。在驱动程序有足够的内存压力之前,RDD 不会自动取消持久化,无论执行程序的 disk/memory 有多满。
- 您不能取消保留 RDD 的一部分(某些 partitions/records)。如果您从另一个构建持久化 RDD,则两者都必须同时完全适合执行程序。
正如@Daniel 所指出的,Spark 将从缓存中删除分区。一旦没有更多可用内存,就会发生这种情况,并且会完成 using a least-recently-used algorithm。正如@eliasah 所指出的,它不是一个智能系统。
如果您没有缓存太多对象,则不必担心。如果缓存太多对象,JVM 收集时间会变得过多,因此在这种情况下取消持久化它们是个好主意。
当我们想要多次使用它时,我们可以将 RDD 持久化到内存 and/or 磁盘中。但是,我们以后是否必须自己取消持久化,或者 Spark 是否会进行某种垃圾收集并在不再需要 RDD 时取消持久化?我注意到如果我自己调用 unpersist 函数,我的性能会变慢。
是的,Apache Spark 会在 RDD 被垃圾回收时取消持久化。
在RDD.persist
中可以看到:
sc.cleaner.foreach(_.registerRDDForCleanup(this))
当 RDD 被垃圾回收时,这会在导致 ContextCleaner.doCleanupRDD
的 ReferenceQueue 中放置对 RDD 的弱引用。还有:
sc.unpersistRDD(rddId, blocking)
有关更多上下文,请参阅一般的 ContextCleaner 和添加它的 commit。
非持久化 RDD 依赖垃圾回收时需要注意的几点:
- RDD 使用执行器上的资源,而垃圾回收发生在驱动器上。在驱动程序有足够的内存压力之前,RDD 不会自动取消持久化,无论执行程序的 disk/memory 有多满。
- 您不能取消保留 RDD 的一部分(某些 partitions/records)。如果您从另一个构建持久化 RDD,则两者都必须同时完全适合执行程序。
正如@Daniel 所指出的,Spark 将从缓存中删除分区。一旦没有更多可用内存,就会发生这种情况,并且会完成 using a least-recently-used algorithm。正如@eliasah 所指出的,它不是一个智能系统。
如果您没有缓存太多对象,则不必担心。如果缓存太多对象,JVM 收集时间会变得过多,因此在这种情况下取消持久化它们是个好主意。