为什么 Spark 的重新分区没有将数据平衡到分区中?


>>> rdd = sc.parallelize(range(10), 2)
>>> rdd.glom().collect()
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>> rdd.repartition(3).glom().collect()
[[], [0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>>

第一个分区为空?为什么?我真的很感谢你告诉我原因。

发生这种情况是因为Spark不会打乱单个元素,而是数据块 - 最小批大小等于10。

因此,如果元素少于每个分区的元素,Spark 不会分隔分区的内容。

这可以通过查看重新分区功能的工作原理来解释。 这样做的原因是,调用df.repartition(COL, numPartitions=k)将使用基于哈希的分区创建具有k分区的数据帧。Pyspark 将遍历每一行并应用以下函数来确定当前行中的元素将结束的位置:

partition_the_row_belongs_to = hash(COL) % k

在这种情况下,k用于将行映射到由 k 个分区组成的空间。如您所见,有时哈希函数会发生冲突。有时有些分区是空的,而另一些分区的元素太多。这可能是因为哈希映射结论,也可能是因为哈希函数。无论哪种方式,您看到的原因是重新分区按照您的要求创建了 3 个分区,它不向您承诺任何有关平衡分区或让所有分区不为空的信息。如果要更好地控制生成的分区的外观,请查看分区依据。

另请参阅:这个问题和这个问题。

我希望这有所帮助。

值得注意的是,由于Spark是关于大规模运行的,因此这是一个不太可能担心的情况。您可以获得的最接近的是偏斜数据。范围将提供与使用哈希的重新分区不同的初始分区。此外,关于批量大小的评论是有效的,但在实践中不太相关。

最新更新