为啥我的随机分区在分组操作期间不是 200(默认)? (火花 2.4.5)

Posted

技术标签:

【中文标题】为啥我的随机分区在分组操作期间不是 200(默认)? (火花 2.4.5)【英文标题】:Why my shuffle partition is not 200(default) during group by operation? (Spark 2.4.5)为什么我的随机分区在分组操作期间不是 200(默认)? (火花 2.4.5) 【发布时间】:2020-08-06 08:05:39 【问题描述】:

我刚接触 spark 并试图了解它的内部结构。所以, 我正在从 s3 读取一个 50MB 的小型 parquet 文件并执行一个分组,然后保存回 s3。 当我观察 Spark UI 时,我可以看到为此创建了 3 个阶段,

阶段 0:加载(1 个任务)

阶段 1:用于分组的 shufflequerystage(12 个任务)

第 2 阶段:保存(coalescedshufflereader)(26 个任务)

代码示例:

df = spark.read.format("parquet").load(src_loc)
df_agg = df.groupby(grp_attribute)\                             
 .agg(F.sum("no_of_launches").alias("no_of_launchesGroup")
df_agg.write.mode("overwrite").parquet(target_loc)

我正在使用具有 1 个主节点、3 个核心节点(每个具有 4 个 vcore)的 EMR 实例。因此,默认并行度为 12。我不会在运行时更改任何配置。但我无法理解为什么在最后阶段创建了 26 个任务?据我了解,默认情况下,shuffle 分区应为 200。附加 UI 的屏幕截图。

【问题讨论】:

哪个版本的 Spark? Spark 2.4.5 @Narsireddy 你能显示代码吗? @thebluephantom 添加 稍后再看 【参考方案1】:

我在使用 Spark 2.4.5 的 Databricks 上尝试了类似的逻辑。

我观察到使用spark.conf.set('spark.sql.adaptive.enabled', 'true'),我的最终分区数是 2。

我观察到使用spark.conf.set('spark.sql.adaptive.enabled', 'false')spark.conf.set('spark.sql.shuffle.partitions', 75),我的分区的最终数量是75。

使用print(df_agg.rdd.getNumPartitions()) 揭示了这一点。

因此,Spark UI 上的作业输出并未反映这一点。可能是在结束时发生重新分区。有趣,但不是真正的问题。

【讨论】:

太棒了。确实是 spark.conf.set('spark.sql.adaptive.enabled', 'true'),它正在减少任务的数量。当我将其设置为 false 时,我会在 UI 中获得 200 个任务。而且,如果我设置了随机分区配置,则上述配置将被忽略。但是,奇怪的是,当我打印 sc.getConf().getAll() 时,我没有看到这个参数。 这也是我的观察,我只见树木不见森林。可能是对答案的接受,它不在 sp v3 中也不是 245 我会再问一个问题 我会接受这个答案,因为它帮助我解决了我的疑问,但不知道为什么您仍然没有在 UI 中看到相同的数字。 好的,我会这样做的。感谢您的帮助:)【参考方案2】:

在 Spark sql 中,shuffle partitions 的数量使用 spark.sql.shuffle.partitions 设置,默认为 200。在大多数情况下,这个数字对于较小的数据来说太高了,对于更大的数据来说太小了。对于开发人员来说,选择正确的值总是很棘手。

因此,我们需要一种通过查看映射器输出来合并 shuffle 分区的能力。如果映射生成的分区数量较少,我们希望减少整体 shuffle 分区,从而提高性能。

在最新的版本中,Spark3.0 带有自适应查询执行,这个减少任务的特性是自动化的。 http://blog.madhukaraphatak.com/spark-aqe-part-2/

考虑到 Spark2.4.5 中的这一点,凯利特优化器或 EMR 可能已启用此功能,以减少内部任务,而不是 200 个任务。

【讨论】:

2.4.5版本和可能? 仅供参考 EMR 有自己的 AQE 版本,他们已为更高版本的 2.x 启用了该版本

以上是关于为啥我的随机分区在分组操作期间不是 200(默认)? (火花 2.4.5)的主要内容,如果未能解决你的问题,请参考以下文章

随机分组的方法都有哪些?

无法在 pyspark 中设置随机分区的数量

固态硬盘装系统分区时扇区是4096还是2048好?为啥分区时固态硬盘默认扇区不是4K而是2048

为啥我的随机数生成器在 C# 中看起来不是随机的?

我efi分区大于200M.为啥mediakit还提示空间不足

为啥我的 Github 托管站点响应 HTTP 302 而不是 200?