PySpark含数亿唯一ID的表按id重分区是否会产生运行低效问题?
Spark重分区问题解答
核心结论
可以直接执行df.repartition("id"),不会生成数亿个分区,你的顾虑不会出现。
底层逻辑说明
- Spark按指定列重分区采用哈希分区策略,若不手动指定分区数量,会默认采用
spark.sql.shuffle.partitions参数的配置值(默认200),分区总数和唯一id的总量没有任何关联。 - 具体实现规则为对
id的值计算哈希值,再对目标分区数取模,相同id的哈希值完全一致,因此所有同id的数据一定会被分配到同一个分区,天然满足同id数据归属同一个worker节点的要求。 - 只有当你手动指定分区数等于唯一id总量,或是使用按范围分区且分区边界设置为每个id一个区间时,才会出现分区数过多的问题,常规按列哈希重分区不会触发该问题。
优化建议
- 你处理的是超大表,默认200分区可能太少导致单分区数据量过大,建议根据总数据量手动指定合理的分区数,写法为
df.repartition(目标分区数, "id"),一般控制单个分区的大小在128MB~256MB区间性能最优。 - 如果后续发现存在个别id对应数据量极大的数据倾斜问题,可再考虑引入加盐哈希的方案优化分区均匀度,无倾斜场景下直接使用原生语法即可。
- 你当前使用的Spark 2.4.0-cdh6.2.1版本完全支持按列名重分区的语法,不存在兼容性问题。
内容的提问来源于stack exchange,提问作者safex
相关产品推荐
相关产品推荐

