Apache spark 在Spark中,缓存数据帧会影响前几个阶段的执行时间吗?
我正在运行一个包含多个阶段的Spark(2.0.1)作业。我注意到,当我在后面的一个阶段中插入一个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分钟)。为什么?
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根据请求添加了有关作业的更多详细信息。谢谢