释放未使用的Spark数据帧占用的内存。

3

我没有对Spark DataFrame进行缓存或持久化操作。如果我需要在同一个会话中对数据框架进行聚合和修改等多个附加操作,则初始数据框架何时释放内存?

例如:

我加载了一个包含1000万条记录的数据框架DF1。然后我对数据框架进行一些转换,创建了一个新的数据框架DF2。然后在DF2上执行了一系列10个步骤。在整个过程中,我不再需要DF1。如何确保DF1不再存在于内存中并且不会影响性能?是否有任何方法可以直接从内存中删除DF1?或者DF1是否根据“最近最少使用”(LRU)的方法自动删除?


你为什么认为需要清除内存? - Steven
2个回答

2
这不是Spark的工作方式。数据框架是惰性加载的...存储在内存中的唯一内容是结构和对数据框架执行的转换列表。数据不会存储在内存中(除非您将它们缓存并应用操作)。
因此,我认为您的问题没有任何问题。

1
@Bonson 我说过了,除非你将其缓存并执行操作,否则它不会存储在内存中。你有缓存它吗?如果是这样,只需要unpersist即可。否则,内存中没有任何内容。 - Steven
1
@bonson,这是基于MapReduce过程的。大部分数据操作都是物理的。Spark使用内存来改进Map过程中的某些操作。但是整个数据框架永远不会完全存储在内存中。 - Steven
如果数据框确实没有存储在内存中,那么为什么当我按照问题中要求的类似示例时,我的Ganglia报告显示使用了150 GB RAM?我甚至告诉Spark将数据框持久化为“DISK_ONLY”,但是集群上的RAM仍然全部用完,性能非常差 - 我认为我需要用图表提出一个新问题... - Nathan T Alexander
@NathanTAlexander 因为Spark使用内存来比仅使用map reduce更快地工作。但是内存仅在解析操作时使用。然后它应该自动释放。数据框架不会存储在内存中,而是在内存中处理。 - Steven
一个 Pantola,看一下我刚刚添加的额外答案。 - Nathan T Alexander
显示剩余3条评论

0
受A Pantola评论中的一个问题的启发,我在此返回并发布了更好的答案。请注意,如何优化RAM使用有许多可能的正确答案,这将取决于正在进行的工作!
首先,将数据框架写入DBFS,类似于以下内容:
spark.createDataFrame(data=[('A',0)],schema=['LETTERS','NUMBERS'])\
    .repartition("LETTERS")\
    .write.partitionBy("LETTERS")\
    .parquet(f"/{tmpdir}",mode="overwrite")

现在,

df = spark.read.parquet(f"/{tmpdir}")

假设您在上述df上没有设置任何缓存,那么每次Spark找到df的引用时,它将并行读取数据框并计算指定的内容。

请注意,上述解决方案将最小化RAM使用量,但可能需要更多的CPU来进行每次读取。此外,上述解决方案将具有写入parquet的成本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接