如果我有一个不再需要的RDD,如何从内存中删除它? 以下是否足以完成这项工作:
del thisRDD
谢谢!
答案 0 :(得分:11)
不,del thisRDD
是不够的,只会删除指向RDD的指针。您应该致电thisRDD.unpersist()
以删除缓存的数据。
对于您的信息,Spark使用延迟计算模型,这意味着当您运行此代码时:
>>> thisRDD = sc.parallelize(xrange(10),2).cache()
您确实没有任何缓存的数据,只会将其标记为' 进行缓存'在RDD执行计划中。你可以这样检查:
>>> print thisRDD.toDebugString()
(2) PythonRDD[6] at RDD at PythonRDD.scala:43 [Memory Serialized 1x Replicated]
| ParallelCollectionRDD[5] at parallelize at PythonRDD.scala:364 [Memory Serialized 1x Replicated]
但是当你在这个RDD上至少调用一次动作时,它会被缓存:
>>> thisRDD.count()
10
>>> print thisRDD.toDebugString()
(2) PythonRDD[6] at RDD at PythonRDD.scala:43 [Memory Serialized 1x Replicated]
| CachedPartitions: 2; MemorySize: 174.0 B; TachyonSize: 0.0 B; DiskSize: 0.0 B
| ParallelCollectionRDD[5] at parallelize at PythonRDD.scala:364 [Memory Serialized 1x Replicated]
您可以使用地址http://<driver_node>:4040/storage
轻松检查Spark UI中的持久数据和持久性级别。你会看到那里del thisRDD
不会改变这个RDD的持久性,但是thisRDD.unpersist()
会解决它的问题,而你仍然可以在你的代码中使用这个RDD(虽然它赢了&#39 ; t不再存在于内存中,每次查询时都会重新计算)
答案 1 :(得分:5)
简短回答:这取决于。
根据pyspark v.1.3.0 source code,del thisRDD
应该足够PipelinedRDD
,这是由Python mapper / reducer生成的RDD:
class PipelinedRDD(RDD):
# ...
def __del__(self):
if self._broadcast:
self._broadcast.unpersist()
self._broadcast = None
另一方面, RDD
课程没有__del__
方法(虽然可能应该这样),所以你应该自己调用unpersist
方法。
修改: __del__
方法已在this提交中删除。
答案 2 :(得分:5)
简答:以下代码可以解决问题:
import gc
del thisRDD
gc.collect()
<强>解释强>
即使您使用的是PySpark,您的RDD数据也会在Java端进行管理,所以首先让我们提出相同的问题,但对于Java而不是Python:
如果我正在使用Java,而我只是释放对RDD的所有引用,那么它是否足以自动取消它?
对于Java,答案是肯定的,根据this answer,RDD在被垃圾收集时将自动取消存在。 (显然,this PR已将功能添加到Spark中。)
好的,Python会发生什么?如果我在Python中删除对RDD的所有引用,是否会导致它们在Java端被删除?
PySpark使用Py4J将对象从Python发送到Java,反之亦然。根据{{3}}:
在Python VM上对对象进行垃圾回收(引用计数== 0)后,将在Java VM上删除引用
但请注意:删除对RDD的Python引用不会导致立即删除。您必须等待Python垃圾收集器清理引用。您可以阅读Py4J的详细说明,他们建议如下:
拨打
gc.collect()
通常也有效。
好的,现在回到原来的问题:
以下是否足以完成这项工作:
del thisRDD
差不多。你应该删除对它的最后一个引用(即del thisRDD
),然后,如果你真的需要立即取消使用RDD **,请致电{{1} }。
**从技术上讲,这将立即删除Java端的引用,但是在Java的垃圾收集器实际执行RDD之前会有一点延迟。终结者,从而使数据不存在。
答案 3 :(得分:2)
仅供参考,
我会在gc.collect()
之后推荐del
(如果rdd占用大量内存)。