在(py)spark中取消持久保存所有数据帧

时间:2016-04-28 05:08:59

标签: python caching apache-spark pyspark apache-spark-sql

我是一个火花应用程序,有几点我想坚持当前的状态。这通常是在一大步之后,或缓存我想要多次使用的状态。看来,当我第二次在我的数据帧上调用缓存时,新副本会缓存到内存中。在我的应用程序中,这会在扩展时导致内存问题。即使在我当前的测试中,给定的数据帧最大约为100 MB,中间结果的累积大小也会超​​出执行程序的分配内存。请参阅下面的一个显示此行为的小示例。

cache_test.py:

from pyspark import SparkContext, HiveContext

spark_context = SparkContext(appName='cache_test')
hive_context = HiveContext(spark_context)

df = (hive_context.read
      .format('com.databricks.spark.csv')
      .load('simple_data.csv')
     )
df.cache()
df.show()

df = df.withColumn('C1+C2', df['C1'] + df['C2'])
df.cache()
df.show()

spark_context.stop()

simple_data.csv:

1,2,3
4,5,6
7,8,9

查看应用程序UI,有一个原始数据框的副本,与新列的副本相对应。我可以通过在withColumn行之前调用df.unpersist()来删除原始副本。这是删除缓存中间结果的推荐方法(即在每个cache()之前调用unpersist。)

此外,是否可以清除所有缓存的对象。在我的应用程序中,有自然断点,我可以简单地清除所有内存,然后转到下一个文件。我想这样做而不为每个输入文件创建一个新的spark应用程序。

提前谢谢!

4 个答案:

答案 0 :(得分:27)

Spark 2.x

您可以使用Catalog.clearCache

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate
...
spark.catalog.clearCache()

Spark 1.x

您可以使用SQLContext.clearCache方法

  

从内存缓存中删除所有缓存的表。

from pyspark.sql import SQLContext
from pyspark import SparkContext

sqlContext = SQLContext.getOrCreate(SparkContext.getOrCreate())
...
sqlContext.clearCache()

答案 1 :(得分:4)

我们经常使用这个

for (id, rdd) in sc._jsc.getPersistentRDDs().items():
    rdd.unpersist()
    print("Unpersisted {} rdd".format(id))

其中sc是sparkContext变量。

答案 2 :(得分:0)

可以单独解决所有df:

firstDF.unpersist()
secondDF.unpersist()

答案 3 :(得分:0)

当您在数据帧上使用缓存时,它是一种转换,当您对它执行任何操作(如count(),show()等)时,都会得到延迟评估。

在您进行第一次高速缓存后,您正在调用show(),这就是数据帧被高速缓存在内存中的原因。现在,您再次对数据框执行转换以添加其他列,并再次缓存新数据框,然后再次调用action命令show,这将在内存中缓存第二个数据框。如果您的数据框的大小足够大,可以容纳一个数据框,那么当您缓存第二个数据框时,它会从内存中删除第一个数据框,因为它没有足够的空间容纳第二个数据框。

要记住的一点:除非要在多个操作中使用它,否则不应该缓存数据帧,否则,由于缓存本身是较昂贵的操作,因此在性能方面会造成过载。