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

时间:2019-04-23 09:45:26

标签: apache-spark pyspark rdd

>>> 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]]
>>>

第一个分区为空?为什么?非常感谢您告诉我原因。

3 个答案:

答案 0 :(得分:2)

之所以会发生这种情况,是因为Spark不会对单个元素进行混洗,而是对数据块with minimum batch size equal to 10进行混洗。

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

答案 1 :(得分:1)

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

partition_the_row_belongs_to = hash(COL) % k

在这种情况下,k用于将行映射到由k个分区组成的空间中。如您所见,哈希函数有时会发生冲突。有时有些分区会是空的,而有些分区会有太多的元素。这可能是由于哈希映射的结论,或者是由于哈希函数。无论哪种方式,您所看到的都是重新分区按照您的要求创建了3个分区,它并不能保证平衡分区或使所有分区都为非空。如果要对生成的分区的外观进行更多控制,请查看partitionby

另请参阅:this questionthis question

我希望能有所帮助。

答案 2 :(得分:0)

值得一提的是,由于Spark完全要大规模运行,因此这种情况不太可能担心。您可以获得的最接近的数据是偏斜的。 range将提供与使用散列的repartition不同的初始分区。此外,有关批处理大小的评论是有效的,但在实践中相关性较低。