提问者:小点点

重新划分后引发非确定性结果


是否有某种方法可以在不排序的情况下从dataframe重新分区中获得确定性结果?在下面的代码中,我在进行相同操作时得到了不同的结果。

from pyspark.sql.functions import rand, randn
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
df = sqlContext.range(0, 100000)

# repartition dataframe to 5 partitions
df2 = df.repartition(5).persist()
df2.head(5)

Out[1]: [Row(id=5324), Row(id=5389), Row(id=6209), Row(id=7640), Row(id=8090)]

df2.unpersist()
df3 = df.repartition(5).persist()
df3.head(5)

Out[2]: [Row(id=1019), Row(id=652), Row(id=2287), Row(id=470), Row(id=1348)]

星火版本-2.4.5


共2个答案

匿名用户

这种非确定性行为是预期的。这是如何…

>

  • . re分区(num)在函数内部没有传递列时执行循环重新分区。这并不能保证特定行将始终位于特定分区中。

    . head(n)返回数据帧第一个分区的前n行。

    如果你想要一个订单,你需要使用orderBy

  • 匿名用户

    根据这个JIRA,重新分区(默认情况下)涉及本地排序,并且是完全确定的。从PR注意到:

    在这PR中,我们建议在分区之前执行局部排序,在我们使输入行排序确定之后,从行到分区的函数也是完全确定的。

    这种方法的缺点是,插入额外的本地排序后,重新分区()的性能会下降,因此我们添加了一个名为的新配置,名为火花. sql.执行.sortBefore重新分区来控制是否应用此补丁。补丁默认启用为默认安全,但用户可以选择手动关闭它以避免性能回归。

    head(n)另一方面不是(除非您应用orderBy它再次将数据集重新分区到一个分区),但这不是您关心的问题,对吗?