Apache spark 在Spark中,缓存数据帧会影响前几个阶段的执行时间吗?

Apache spark 在Spark中,缓存数据帧会影响前几个阶段的执行时间吗?,apache-spark,caching,Apache Spark,Caching,我正在运行一个包含多个阶段的Spark(2.0.1)作业。我注意到,当我在后面的一个阶段中插入一个cache()时,它会更改早期阶段的执行时间。为什么?在阅读有关缓存()的文章时,我在文献中从未遇到过这样的情况 这是我的带有缓存()的DAG: 这是我的DAG,没有cache()。所有剩余的代码都是相同的 在第10阶段的排序合并联接之后,我有一个cache()。如果在阶段10中使用了cache(),那么阶段8的时间比阶段10中没有cache()的时间长近两倍(20分钟vs 11分钟)。为什么?

我正在运行一个包含多个阶段的Spark(2.0.1)作业。我注意到,当我在后面的一个阶段中插入一个
cache()
时,它会更改早期阶段的执行时间。为什么?在阅读有关缓存()的文章时,我在文献中从未遇到过这样的情况

这是我的带有
缓存()的DAG

这是我的DAG,没有
cache()
。所有剩余的代码都是相同的

在第10阶段的排序合并联接之后,我有一个
cache()
。如果在阶段10中使用了
cache()
,那么阶段8的时间比阶段10中没有
cache()
的时间长近两倍(20分钟vs 11分钟)。为什么?

我的Stage8包含两个带有小数据帧的广播连接和一个大数据帧上的洗牌,以准备合并连接。阶段8和9是独立的,在两个不同的数据帧上运行

如果你需要更多的细节来回答这个问题,请告诉我

更新8/2/1018 以下是我的Spark脚本的详细信息:

我正在通过spark submit在集群上运行我的作业。这是我的spark课程

   val spark = SparkSession.builder
      .appName("myJob")
      .config("spark.executor.cores", 5)
      .config("spark.driver.memory", "300g")
      .config("spark.executor.memory", "15g")
      .getOrCreate()
这将创建一个作业,其中有21个执行器,每个执行器有5个cpu

从拼花文件加载4个数据帧:

val dfT = spark.read.format("parquet").load(filePath1) // 3 Tb in 3185 partitions
val dfO = spark.read.format("parquet").load(filePath2) // ~ 700 Mb
val dfF = spark.read.format("parquet").load(filePath3) // ~ 800 Mb
val dfP = spark.read.format("parquet").load(filePath4) // 38 Gb
对每个
数据帧
的预处理包括列选择和
删除重复项
以及可能的
过滤器
,如下所示:

val dfT1 = dfT.filter(...)
val dfO1 = dfO.select(columnsToSelect2).dropDuplicates(Array("someColumn2"))
val dfF1 = dfF.select(columnsToSelect3).dropDuplicates(Array("someColumn3"))
val dfP1 = dfP.select(columnsToSelect4).dropDuplicates(Array("someColumn4"))
然后我离开广播,将前三个数据帧连接在一起:

val dfTO = dfT1.join(broadcast(dfO1), Seq("someColumn5"), "left_outer")
val dfTOF = dfTO.join(broadcast(dfF1), Seq("someColumn6"), "left_outer")
由于
dfP1
很大,我需要进行合并联接,我现在负担不起。我需要首先限制
dfTOF
的大小。为此,我添加了一个新的timestamp列,它是一个
withColumn
,带有一个将字符串转换为时间戳的UDF

val dfTOF1 = dfTOF.withColumn("TransactionTimestamp", myStringToTimestampUDF)
接下来,我在新的时间戳列上进行筛选:

val dfTrain = dfTOF1.filter(dfTOF1("TransactionTimestamp").between("2016-01-01 00:00:00+000", "2016-05-30 00:00:00+000"))
现在我加入最后一个
数据帧

val dfTrain2 = dfTrain.join(dfP1, Seq("someColumn7"), "left_outer")
最后是一个列选择,其中包含一个cache(),这让我很困惑

val dfTrain3 = dfTrain.select("columnsToSelect5").cache()
dfTrain3.agg(sum(col("someColumn7"))).show()
看起来
cache()
在这里是无用的,但是
DataFrame
将有一些进一步的处理和建模,而
cache()
将是必要的


我应该提供更多细节吗?您想看一下dfTrain3的执行计划吗?

我们这里肯定需要更多的细节。一般来说,这并不罕见,但细节取决于特定场景。有关提示,请参阅“如何创建有用的示例”。@user6910411根据请求添加了有关作业的更多详细信息。谢谢