如何解决分区后产生不确定的结果
是否可以通过某种方式从数据帧重新划分中获得确定性的结果而不进行排序?在下面的代码中,执行相同的操作会得到不同的结果。
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)]
Spark版本-2.4.5
解决方法
此non deterministic
行为是expected
。这就是...
-
当没有在函数内部传递任何列时,
-
.repartition(num)
进行round-robin
重分区。这不能保证特定的行将始终位于特定的分区中。 -
.head(n)
返回数据帧的第一个分区的前n行。
如果要订购,则需要使用orderBy
!
根据此JIRA,重新分区(默认情况下)涉及局部排序,并且完全是确定性的。从PR注释中:
另一方面,在此PR中,我们建议...在执行局部排序之前 划分,确定输入行的顺序后, 从行到分区的功能也是完全确定的。
该方法的缺点是,插入了额外的本地排序, repartition()的性能将下降,因此我们添加了一个新配置 命名为
spark.sql.execution.sortBeforeRepartition
以控制是否 此补丁已应用。该补丁默认启用为 默认情况下安全,但用户可以选择手动将其关闭以避免 性能回归。
head(n)
不是(除非您应用orderBy
它将再次将数据集重新分区到一个分区),但这不是您所关心的吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。