在Spark中,缓存DataFrame会影响前一阶段的执行时间吗?

时间:2018-02-07 16:08:50

标签: apache-spark caching

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

以下是我的DAG cache()

myDAGwithCache

这是我的DAG没有cache()。剩下的所有代码都是一样的。

myDAGwithoutCache

在Stage10中进行排序合并连接后,我有一个cache()。如果在Stage10中使用cache(),那么如果Stage10中没有cache(),则Stage8将近两倍(20分钟对11分钟)。为什么呢?

My Stage8包含两个带有小型DataFrame的广播连接和一个用于准备合并连接的大型DataFrame上的shuffle。阶段8和9是独立的,可以在两个不同的数据框架上运行。

如果您需要更多详细信息来回答此问题,请与我们联系。

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

我通过spark-submit在集群上运行我的工作。这是我的火花会议。

   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 DataFrames

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

每个DataFrames的预处理由列选择和dropDuplicates以及可能filter组成,如下所示:

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"))

然后我将前三个DataFrames左边的广播连接在一起:

val dfTO = dfT1.join(broadcast(dfO1), Seq("someColumn5"), "left_outer")
val dfTOF = dfTO.join(broadcast(dfF1), Seq("someColumn6"), "left_outer")

由于dfP1很大,我需要进行合并加入,我现在无法承担。我需要先限制dfTOF的大小。为此,我添加了一个新的时间戳列,它是一个带有UDF的withColumn,它将字符串转换为时间戳

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"))

现在我加入了最后一个DataFrame

val dfTrain2 = dfTrain.join(dfP1, Seq("someColumn7"), "left_outer")

最后,使用缓存()的列选择令我感到困惑。

val dfTrain3 = dfTrain.select("columnsToSelect5").cache()
dfTrain3.agg(sum(col("someColumn7"))).show()

看起来cache()在这里没用,但会有一些DataFramecache()的进一步处理和建模。

我应该提供更多细节吗?您是否希望查看dfTrain3的执行计划?

0 个答案:

没有答案