(py)spark数据帧跨多个id重分区



我有一个巨大的表,我的火花工作不断崩溃。我想重新划分它。我有两个变量(id,time),我需要确保具有给定id的所有行将被分区到相同的worker。但我有数以亿计的唯一id。我希望pyspark均匀地分布数据,但尊重给定ID的所有行应该在一个worker上。

df.repartition("id")

文档似乎是这样建议的。但是我想知道spark现在是否会将作业划分为数亿个子集,并且一次只发送一个子集(即一个id的数据)给每个worker。这当然是非常低效的。

我正在使用Spark 2.4.0-cdh6.2.1

让我们使用explain来看看当您调用repartition时spark会做什么:

>>> spark.range(20).repartition("id").explain()
== Physical Plan ==
Exchange hashpartitioning(id#0L, 200)
+- *(1) Range (0, 20, step=1, splits=8)

Exchange hashpartitioning(id#0L, 200)表示将数据转移到200个分区中。一行最终所在的分区是通过执行id.hashCode() % 200来确定的。如果你的数据没有歪斜,分布应该是相当均匀的。200是spark.sql.shuffle.partitions的默认值,它决定了shuffle后生成多少分区。要将该值更改为400,您可以将配置的值更改为执行spark.conf.set("spark.sql.shuffle.partitions", 400)或执行repartition(400, "id")。事实上,如果你有很多数据,200可能是不够的。