首页 > 解决方案 > (py)跨多个ID的spark数据帧重新分区

问题描述

我有一张巨大的桌子,我的火花工作一直在崩溃。我想重新分区。我有两个变量(id, time),我需要在其中确保具有给定的所有行都id将被分配给同一个工作人员。但我有数亿个唯一 ID。我希望 pyspark 均匀分布数据,但尊重给定 ID 的所有行都应该在一个工作人员上。我可以简单地做:

df.repartition("id")

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

我正在使用 Spark 2.4.0-cdh6.2.1

标签: pythonapache-sparkpysparkpartitioning

解决方案


让我们explain看看调用时 spark 的作用repartition

>>> 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 个分区中。行最终所在的分区由 do 确定id.hashCode() % 200。如果您的数据没有偏差,则分布应该非常均匀。200 是它的默认值,spark.sql.shuffle.partitions它决定了 shuffle 后生成了多少个分区。要将该值更改为 400,您可以将配置的值更改为spark.conf.set("spark.sql.shuffle.partitions", 400)do 或 do repartition(400, "id")。事实上,如果你有很多数据,200 可能还不够。


推荐阅读