-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-32932][SQL] Do not use local shuffle reader at final stage on write command #29797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
84134b0
b112133
f05b458
4fdee62
39dc4ca
364ee28
d391269
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,7 @@ import org.apache.spark.sql.catalyst.rules.{PlanChangeLogger, Rule} | |
| import org.apache.spark.sql.catalyst.trees.TreeNodeTag | ||
| import org.apache.spark.sql.execution._ | ||
| import org.apache.spark.sql.execution.adaptive.AdaptiveSparkPlanExec._ | ||
| import org.apache.spark.sql.execution.command.DataWritingCommandExec | ||
| import org.apache.spark.sql.execution.exchange._ | ||
| import org.apache.spark.sql.execution.ui.{SparkListenerSQLAdaptiveExecutionUpdate, SparkListenerSQLAdaptiveSQLMetricUpdates, SQLPlanMetric} | ||
| import org.apache.spark.sql.internal.SQLConf | ||
|
|
@@ -102,6 +103,14 @@ case class AdaptiveSparkPlanExec( | |
| OptimizeLocalShuffleReader(conf) | ||
| ) | ||
|
|
||
| @transient private val finalStageOptimizerRules: Seq[Rule[SparkPlan]] = | ||
| context.qe.sparkPlan match { | ||
| case _: DataWritingCommandExec => | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need to match all writing commands, including DS v1, v2 and file source. Maybe we can create a tagging trait like
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems DSv2 is not ready for write as per https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/DataFrameWriter.scala#L988-L994. Meanwhile, will it too big a change for those interfaces to extend the tagging trait ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. File source v2 is not ready yet, but it doesn't mean DS v2 is not ready for writing. Please follow
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, is there a UT for DS v2 write ? I find only V1 is used for write no matter format I specify.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added match for |
||
| queryStageOptimizerRules.filterNot(_.isInstanceOf[OptimizeLocalShuffleReader]) | ||
|
dongjoon-hyun marked this conversation as resolved.
|
||
| case _ => | ||
| queryStageOptimizerRules | ||
| } | ||
|
|
||
| // A list of physical optimizer rules to be applied right after a new stage is created. The input | ||
| // plan to these rules has exchange as its root node. | ||
| @transient private val postStageCreationRules = Seq( | ||
|
|
@@ -235,7 +244,7 @@ case class AdaptiveSparkPlanExec( | |
| // Run the final plan when there's no more unfinished stages. | ||
| currentPhysicalPlan = applyPhysicalRules( | ||
| result.newPlan, | ||
| queryStageOptimizerRules ++ postStageCreationRules, | ||
| finalStageOptimizerRules ++ postStageCreationRules, | ||
| Some((planChangeLogger, "AQE Final Query Stage Optimization"))) | ||
| isFinalPlan = true | ||
| executionId.foreach(onUpdatePlan(_, Seq(currentPhysicalPlan))) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ import org.apache.spark.sql.execution.joins.{BaseJoinExec, BroadcastHashJoinExec | |
| import org.apache.spark.sql.execution.ui.SparkListenerSQLAdaptiveExecutionUpdate | ||
| import org.apache.spark.sql.functions._ | ||
| import org.apache.spark.sql.internal.SQLConf | ||
| import org.apache.spark.sql.internal.SQLConf.PartitionOverwriteMode | ||
| import org.apache.spark.sql.test.SharedSparkSession | ||
| import org.apache.spark.sql.types.{IntegerType, StructType} | ||
| import org.apache.spark.util.Utils | ||
|
|
@@ -1258,4 +1259,25 @@ class AdaptiveQueryExecSuite | |
| } | ||
| } | ||
| } | ||
|
|
||
| test("SPARK-32932: Do not use local shuffle reader at final stage on DataWritingCommand") { | ||
| withSQLConf(SQLConf.PARTITION_OVERWRITE_MODE.key -> PartitionOverwriteMode.DYNAMIC.toString, | ||
| SQLConf.SHUFFLE_PARTITIONS.key -> "5", | ||
| SQLConf.ADAPTIVE_EXECUTION_ENABLED.key -> "true", | ||
| SQLConf.COALESCE_PARTITIONS_ENABLED.key -> "true") { | ||
| withTable("t") { | ||
| val data = for ( | ||
| i <- 1 to 10; | ||
| j <- 1 to 3 | ||
| ) yield (i, j) | ||
| data.toDF("a", "b") | ||
| .repartition($"b") | ||
| .write | ||
| .partitionBy("b") | ||
| .mode("overwrite") | ||
| .saveAsTable("t") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto: put in one line |
||
| assert(spark.read.table("t").inputFiles.length == 3) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a bit tricky to check the number of files. 3 distinct values don't always mean 3 files. Can we use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests have been updated with |
||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's only called once, can be a
def