首页 > 解决方案 > 如果对中间结果应用两个不同的转换,火花是否会重新计算中间结果?

问题描述

假设我们从一些数据开始,得到一些中间结果df_intermediate。沿着从源数据到 的管道df_intermediate,所有转换都是惰性的,实际上没有计算任何内容。

然后我想对df_intermediate. 例如,我想计算df_intermediate.agg({"col":"max"})df_intermediate.approxquantile("col", [0.1,0.2,0.3], 0.01)使用两个单独的命令。

我想知道在以下场景中,sparkdf_intermediate在执行第二次转换时是否需要重新计算?换句话说,Spark 是否对上述两个转换进行计算,都是从原始数据开始,而不存储中间结果?显然我可以缓存中间结果,但我只是想知道 Spark 是否在内部进行了这种优化。

标签: apache-sparkpyspark

解决方案


这有点令人失望。但首先你需要从动作的角度来看待它。我不会考虑缓存。

如果您执行以下操作,肯定会有优化。

val df1 = df0.withColumn(...
val df2 = df1.withColumn(...

您的示例需要类似计数的操作才能工作。但是这两个语句过于多样化,因此没有明显的跳过处理。因此没有共享。

一般来说,Action = Job 是正确的看待它的方式。对于 DF,Catalyst Optimizer 可以启动作业,即使您可能没有意识到这一点。对于 RRD(遗留)来说,这有点不同。

这也没有得到优化:

import org.apache.spark.sql.functions._
val df = spark.range(1,10000).toDF("c1")
val df_intermediate = df.withColumn("c2", col("c1") + 100) 
val x = df_intermediate.agg(max("c2"))  
val y = df_intermediate.agg(min("c2")) 
val z = x.union(y).count  

x 和 y 都返回源。人们会认为这样做会更容易,而且这里也是 1 Action。需要做.explain,但由于懒惰的评估等原因,这个想法是把它留给Spark。

顺便说一句:为多次引用该数据帧的单个 Action Spark 应用程序缓存数据帧是否有效?&在哪些情况下会跳过 DAG 的阶段?


推荐阅读