PySpark DataFrame内存释放疑问:unpersist后仍可访问数据求正确方法
问题描述
我执行了以下PySpark代码,试图清除DataFrame并释放内存,但执行df4.show()时仍能正常显示数据:
from pyspark.sql import SparkSession from pyspark import SparkContext, SparkConf from pyspark.storagelevel import StorageLevel spark = SparkSession.builder.appName('TEST').config('spark.ui.port','4098').enableHiveSupport().getOrCreate() df4 = spark.sql('select * from hive_schema.table_name limit 1') print("query completed" ) df4.unpersist() df4.count() df4.show()
请问释放PySpark DataFrame占用内存的正确方法是什么?
解决方案
首先要明确:PySpark的unpersist()仅作用于主动缓存(通过cache()/persist()方法标记缓存)的DataFrame,它的功能是移除已缓存的内存/磁盘数据,但不会销毁DataFrame对象本身,也无法阻止Spark重新计算该DataFrame的内容。
你代码里的核心问题是:
- 从未对
df4执行过cache()或persist(),所以unpersist()实际上没有任何操作 - 调用
df4.count()和df4.show()时,Spark会重新执行spark.sql()中的查询语句,重新生成数据,因此仍能看到结果
针对不同场景,正确的内存释放方式如下:
1. 针对已缓存的DataFrame
如果主动缓存了DataFrame,需要两步操作彻底释放资源:
- 调用
df4.unpersist(blocking=True):blocking=True会等待缓存数据完全从内存/磁盘中移除后再返回,确保资源被释放 - 将DataFrame变量置为
None,触发Python垃圾回收机制销毁对象
示例:
df4 = spark.sql('select * from hive_schema.table_name limit 1') # 主动缓存数据 df4.cache() # 执行计算操作 df4.count() # 释放缓存数据 df4.unpersist(blocking=True) # 销毁DataFrame对象 df4 = None
2. 针对未缓存的DataFrame
未缓存的DataFrame,Spark会在任务执行完成后自动清理中间数据,但如果想主动终止后续对该DataFrame的使用:
- 直接将变量置为
None,让Python垃圾回收器回收对象 - 若需要清空所有缓存的表和DataFrame,可调用
spark.catalog.clearCache()一次性清理全局缓存
关键注意事项
- PySpark DataFrame是惰性计算模型,只有遇到行动算子(如
count()、show())时才会执行查询。只要DataFrame对象未被销毁,调用行动算子就会重新触发计算 - 区分“释放缓存”和“销毁对象”:
unpersist()只处理缓存数据,销毁对象依赖Python的垃圾回收机制
内容的提问来源于stack exchange,提问作者Anand Reddy
相关产品推荐
相关产品推荐

