[英]What is shufflequerystage in spark DAG?
這里已經有一個很好的答案,但這只是為了通過查看源代碼為您提供更多關於這個shufflequerystage
實際上是什么的信息。
如果我們查看ShuffleQueryStageExec案例類的 Spark 源代碼,我們會看到以下內容:
case class ShuffleQueryStageExec(
override val id: Int,
override val plan: SparkPlan,
override val _canonicalized: SparkPlan) extends QueryStageExec {
...
}
所以ShuffleQueryStageExec extends QueryStageExec
。 那么讓我們看看QueryStageExec 。 代碼注釋很有啟發性:
查詢階段是查詢計划的獨立子圖。 查詢階段在繼續執行查詢計划的進一步運算符之前具體化其輸出。 物化輸出的數據統計可用於優化后續查詢階段。
有兩種查詢階段:
- 隨機查詢階段。 這個階段將其輸出具體化為隨機文件,Spark 啟動另一個作業來執行更多操作符。
- 廣播查詢階段。 此階段將其輸出具體化為驅動程序 JVM 中的一個數組。 Spark 在執行進一步的運算符之前廣播數組。
所以(非常)簡而言之, ShuffleQueryStage
是您整個查詢計划的一部分,其數據統計信息可用於優化后續查詢階段。 這些都是自適應查詢執行(AQE) 的一部分。
為了更好地了解這一切是如何工作的,我們可以嘗試了解隨機查詢階段是如何進行的。 AdaptiveSparkPlanExec案例類是這方面的有趣位置。
有許多動作(收集、獲取、拖尾、執行……)會觸發withFinalPlanUpdate
函數,而后者又會觸發getFinalPhysicalPlan
函數。 在此函數中,將調用createQueryStages函數,這就是它變得有趣的地方。
createQueryStages函數是一個遍歷整個計划樹的遞歸函數,它看起來有點像這樣:
private def createQueryStages(plan: SparkPlan): CreateStageResult = plan match {
case e: Exchange =>
// First have a quick check in the `stageCache` without having to traverse down the node.
context.stageCache.get(e.canonicalized) match {
case Some(existingStage) if conf.exchangeReuseEnabled =>
...
case _ =>
val result = createQueryStages(e.child)
val newPlan = e.withNewChildren(Seq(result.newPlan)).asInstanceOf[Exchange]
// Create a query stage only when all the child query stages are ready.
if (result.allChildStagesMaterialized) {
var newStage = newQueryStage(newPlan)
...
}
所以你看,如果我們反彈到一個已經執行過的Exchange
並且我們想重用它,我們就這樣做。 但如果不是這種情況,我們將創建一個新計划並調用newQueryStage
函數。
故事到此結束。 newQueryStage
函數如下所示:
private def newQueryStage(e: Exchange): QueryStageExec = {
val optimizedPlan = optimizeQueryStage(e.child, isFinalStage = false)
val queryStage = e match {
case s: ShuffleExchangeLike =>
...
ShuffleQueryStageExec(currentStageId, newShuffle, s.canonicalized)
case b: BroadcastExchangeLike =>
...
BroadcastQueryStageExec(currentStageId, newBroadcast, b.canonicalized)
}
...
}
所以我們看到正在制作ShuffleQueryStageExec
! 因此,對於每個Exchange
,這還沒有發生,或者如果您沒有重復使用交換,AQE 將添加ShuffleQueryStageExec
或BroadcastQueryStageExec
。
希望這能讓人們更深入地了解這是什么:)
shufflequerystage 連接到 AQE,它們在每個階段之后添加並進行交換,用於在每個階段之后具體化結果並根據統計信息優化剩余計划。
所以我的簡短回答是:
交換 - 在這里你的數據被洗牌
Shufflequerystage - 添加用於 AQE 目的以使用運行時統計信息和重新優化計划
在下面的示例中,我試圖展示這種機制
這是示例代碼:
import org.apache.spark.sql.functions._
spark.conf.set("spark.sql.autoBroadcastJoinThreshold", -1)
spark.conf.set("spark.sql.adaptive.enabled", true)
val input = spark.read
.format("csv")
.option("header", "true")
.load(
"dbfs:/FileStore/shared_uploads/**@gmail.com/city_temperature.csv"
)
val dataForInput2 = Seq(
("Algeria", "3"),
("Germany", "3"),
("France", "5"),
("Poland", "7"),
("test55", "86")
)
val input2 = dataForInput2
.toDF("Country", "Value")
.withColumn("test", lit("test"))
val joinedDfs = input.join(input2, Seq("Country"))
val finalResult =
joinedDfs.filter(input("Country") === "Poland").repartition(200)
finalResult.show
我正在從文件中讀取數據,但你可以用代碼中創建的小 df 替換它,因為我添加了一行來禁用廣播。 我添加了一些 withColumn 和 repartition 以使其更有趣
首先讓我們看一下禁用 AQE 的計划:
== Physical Plan ==
CollectLimit (11)
+- Exchange (10)
+- * Project (9)
+- * SortMergeJoin Inner (8)
:- Sort (4)
: +- Exchange (3)
: +- * Filter (2)
: +- Scan csv (1)
+- Sort (7)
+- Exchange (6)
+- LocalTableScan (5)
現在啟用 AQE
== Physical Plan ==
AdaptiveSparkPlan (25)
+- == Final Plan ==
CollectLimit (16)
+- ShuffleQueryStage (15), Statistics(sizeInBytes=1447.8 KiB, rowCount=9.27E+3, isRuntime=true)
+- Exchange (14)
+- * Project (13)
+- * SortMergeJoin Inner (12)
:- Sort (6)
: +- AQEShuffleRead (5)
: +- ShuffleQueryStage (4), Statistics(sizeInBytes=1158.3 KiB, rowCount=9.27E+3, isRuntime=true)
: +- Exchange (3)
: +- * Filter (2)
: +- Scan csv (1)
+- Sort (11)
+- AQEShuffleRead (10)
+- ShuffleQueryStage (9), Statistics(sizeInBytes=56.0 B, rowCount=1, isRuntime=true)
+- Exchange (8)
+- LocalTableScan (7)
代碼是一樣的,唯一不同的是 AQE 但現在你可以看到每次交換后都會彈出 ShuffleQueryStage
讓我們看一下示例中的 Dag 可視化。
首先讓我們看一下包含 join 的 job3
然后是 job4 ,它只是重用之前計算的內容,但使用 ShuffleQueryStage 添加了額外的第 4 階段,與您的情況類似
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.