什么是混洗分区?

Tan*_*ark 1 partitioning apache-spark pyspark

什么是spark.sql.shuffle.partitions更技术意义上的?我见过像这里这样的答案它说:“配置在混洗数据以进行连接或聚合时使用的分区数。”

这实际上意味着什么?当这个数字更高或更低时,从一个节点到另一个节点的改组如何不同?

谢谢!

Dan*_*iel 6

分区定义了数据在集群中的位置。单个分区可以包含多行,但所有行都将在一个节点上的单个任务中一起处理。

在边缘情况下,如果我们将数据重新分区到一个分区中,即使您有 100 个 executor,它也只会被一个处理。 单分区说明

另一方面,如果您有一个执行程序,但有多个分区,它们将(显然)在同一台机器上处理。 在此处输入图片说明

当一个执行器需要来自另一个执行器的数据时,会发生混洗 - 基本示例是 groupBy 聚合操作,因为我们需要所有相关的行来计算结果。不管我们在 groupBy 之前有多少个分区,在它 spark 之后都会将结果拆分为spark.sql.shuffle.partitions

引用 Bill Chambers 和 Matei Zaharia 的“Spark——权威指南”:

一个好的经验法则是分区的数量应该大于集群上的执行程序的数量,这可能取决于工作负载的多种因素。如果您在本地机器上运行代码,则您应该将此值设置得较低,因为您的本地机器不太可能并行执行该数量的任务。

因此,总而言之,如果您将此数字设置为低于集群运行任务的容量,您将无法使用其所有资源。另一方面,由于任务在单个分区上运行,因此拥有数千个小分区(我预计)会产生一些开销。

  • 不完全是。任务使用不同的算法将数据保存到“随机文件”中,然后在节点之间压缩和发送该数据的另一层。因此,处理单个分区的结果可能会产生多个分区。如果您按一个键分区,然后由另一个工作人员分组,则会交换必要的行,但这将是非常繁重的操作。重要的是 Spark 将尝试始终优化执行计划 - 例如,如果您针对非常小的数据帧运行 join,它可以广播到所有执行器并保留在内存中。 (2认同)