假设我有一个函数来生成 (py)spark 数据帧,将数据帧缓存到内存中作为最后一个操作。
def gen_func(inputs):
df = ... do stuff...
df.cache()
df.count()
return df
Run Code Online (Sandbox Code Playgroud)
根据我的理解,Spark 的缓存工作如下:
cache/persistplus 一个动作 ( count()) 时,它是从它的 DAG 计算出来的,并缓存到内存中,附加到引用它的对象上。我的问题是,假设我gen_func用来生成一个数据框,然后覆盖原始数据框引用(可能是 afilter或 a withColumn)。
df=gen_func(inputs)
df=df.filter("some_col = some_val")
Run Code Online (Sandbox Code Playgroud)
在 Spark 中,RDD/DF 是不可变的,因此过滤器后重新分配的 df 和过滤器前的 df 指的是两个完全不同的对象。在这种情况下,对原始 df 的引用cache/counted已被覆盖。这是否意味着缓存的数据帧不再可用并将被垃圾收集?这是否意味着新的后置过滤器df将从头开始计算所有内容,尽管是从先前缓存的数据帧生成的?
我问这个是因为我最近正在修复我的代码的一些内存不足问题,在我看来,缓存可能是问题所在。然而,我还没有真正理解什么是使用缓存的安全方法的全部细节,以及人们如何可能不小心使自己的缓存内存无效。我的理解中缺少什么?我在执行上述操作时是否偏离了最佳实践?