簡體   English   中英

spark.sql.shuffle.partitions 和 spark.default.parallelism 有什么區別?

[英]What is the difference between spark.sql.shuffle.partitions and spark.default.parallelism?

spark.sql.shuffle.partitionsspark.default.parallelism之間有什么區別?

我嘗試在SparkSQL中設置它們,但是第二階段的任務號始終是 200。

這里的答案來看, spark.sql.shuffle.partitions配置了混洗數據以進行連接或聚合時使用的分區數。

spark.default.parallelismRDDjoinreduceByKeyparallelize等轉換返回的默認分區數,當用戶未明確設置時。 請注意, spark.default.parallelism似乎只適用於原始RDD ,在處理數據幀時會被忽略。

如果您正在執行的任務不是連接或聚合,並且您正在使用數據幀,那么設置這些將不會產生任何影響。 但是,您可以通過在代碼中調用df.repartition(numOfPartitions) (不要忘記將其分配給新的val )來自己設置分區數。


要更改代碼中的設置,您只需執行以下操作:

sqlContext.setConf("spark.sql.shuffle.partitions", "300")
sqlContext.setConf("spark.default.parallelism", "300")

或者,您可以在使用spark-submit將作業提交到集群時進行更改:

./bin/spark-submit --conf spark.sql.shuffle.partitions=300 --conf spark.default.parallelism=300

spark.default.parallelism是 spark 設置的默認分區數,默認為 200。如果你想增加分區數,你可以應用屬性spark.sql.shuffle.partitions來設置分區數spark 配置或在運行 spark SQL 時。

通常這個spark.sql.shuffle.partitions當我們有內存擁塞並且我們看到以下錯誤時會使用它:spark error:java.lang.IllegalArgumentException: Size exceeded Integer.MAX_VALUE

所以設置你可以為每個分區分配一個 256 MB 的分區,你可以用它來設置你的進程。

此外,如果分區數接近 2000,則將其增加到 2000 以上。由於 spark 對 <2000 和 > 2000 的分區應用不同的邏輯,這將通過減少內存占用來提高代碼性能,因為如果 >2000,數據默認值會被高度壓縮。

如果有人可能想知道,當設置spark.sql.shuffle.partitions可能變得無效時,確實存在特殊情況。 當您重新啟動具有相同檢查點位置的結構化流式 Spark 應用程序時,更改此術語不會生效。 https://spark.apache.org/docs/latest/configuration.html#runtime-sql-configuration中查看更多信息

添加到已經發布的一些很棒的答案中:

TLDR

  • spark.sql.shuffle.partitions
    • 確定在對Dataframes/Datasets進行廣泛操作后將擁有多少個 output 分區。
    • 它的默認值為 200。
  • spark.default.parallelism
    • 是一個更復雜的參數,在 Spark 中更“深入”。 它影響:
      • 如果不指定數量,對RDD進行廣泛操作后將擁有多少個分區
      • sc.parallelize創建了多少個分區
      • 執行spark.read.csv時讀取了多少個分區,...
    • 它的默認值取決於您在哪種類型的集群上執行何種類型的操作。

spark.sql.shuffle.partitions

文檔

為連接或聚合混洗數據時使用的默認分區數。 注意:對於結構化流,此配置不能在從同一檢查點位置重新啟動的查詢之間更改。

從 Spark 3.3.1(本文發布時的最新版本) SQLConf.scala中可以看出, spark.sql.shuffle.partitions的默認值為 200。

  val SHUFFLE_PARTITIONS = buildConf("spark.sql.shuffle.partitions")
    .doc("The default number of partitions to use when shuffling data for joins or aggregations. " +
      "Note: For structured streaming, this configuration cannot be changed between query " +
      "restarts from the same checkpoint location.")
    .version("1.1.0")
    .intConf
    .checkValue(_ > 0, "The value of spark.sql.shuffle.partitions must be positive")
    .createWithDefault(200)

結論:這是一個可以對數據幀/數據集上的廣泛轉換(連接、排序等)產生直接影響的值。 您將能夠使用此參數配置這些寬轉換的 output 個分區的數量。

spark.default.parallelism

文檔

當用戶未設置時,由連接、reduceByKey 和並行化等轉換返回的 RDD 中的默認分區數。

關於它的默認值:

對於像reduceByKeyjoin這樣的分布式洗牌操作,父 RDD 中的最大分區數。 對於像沒有父 RDD 的parallelize這樣的操作,它取決於集群管理器:

  • 本地模式:本地機器上的核心數
  • Mesos 細粒度模式:8
  • 其他:所有執行器節點上的核心總數或2,以較大者為准

所以我們已經看到這個參數有點復雜。 它沒有真正的默認值,但您可以設置它。 如果我們看一些代碼,這會變得更清楚。

SparkContext.scala中,我們看到defaultParallelism是如何定義的:

/** Default level of parallelism to use when not given by user (e.g. parallelize and makeRDD). */
def defaultParallelism: Int = {
  assertNotStopped()
  taskScheduler.defaultParallelism
}

所以我們看到這個defaultParallelism依賴於 taskScheduler 的類型(比如 docs 狀態)。 讓我們來看看那些:

override def defaultParallelism(): Int =
  scheduler.conf.getInt("spark.default.parallelism", totalCores)
override def defaultParallelism(): Int = sc.conf.getInt("spark.default.parallelism", 8)
  • 其他CoarseGrainSchedulerBackend ):
override def defaultParallelism(): Int = {
  conf.getInt("spark.default.parallelism", math.max(totalCoreCount.get(), 2))
}

好的,現在我們明白這個值有點復雜讓我們試着弄清楚它何時相關:

  • 在對RDD進行廣泛的轉換時。 joinreduceByKeygroupByKey等都使用defaultPartitioner如果沒有給出分區作為輸入參數。 在那個defaultPartitioner中, spark.default.parallelism用於確定分區的數量。
  • Seq上調用sc.parallelize時。 根據您的集群管理器,您將獲得 output 個分區,如上所述。
  • 在讀入數據時(例如spark.read.csv ),會影響讀入多少個分區。在DataSourceScanExeccreateReadRDD function中,讀入output個分區的數量受maxSplitBytes的影響function,它本身受spark.default.parallelism的影響,如SO answer中所述。
  • 我確定它在更多地方使用,但我希望這已經給出了關於此參數的更多直覺。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM