首页/数据/数仓建模速查/Spark 并行度调参:shuffle partitions
湖仓与引擎63 条

Spark 并行度调参:shuffle partitions

spark.sql.shuffle.partitions 决定 shuffle 后分区数,偏小导致单分区过大、偏大产生小文件;经验值让单分区处理 100-200MB 数据。

数仓建模速查数据更新于 2026-10-13

shuffle 并行度是什么

Spark SQL 里 spark.sql.shuffle.partitions 决定 shuffle 之后产生多少个分区,也就是 join、group by 这类算子下游的并行度,默认值是 200。分区偏小,单个 task 要处理的数据过多,容易内存溢出并放大倾斜;分区偏大,task 数与输出文件数同步膨胀,调度开销和小文件问题接踵而来。经验做法是先估算总 shuffle 数据量,再按单个分区 100-200MB 反推分区数,剩下的交给 AQE 在运行时合并或拆分。

基本信息

核心参数spark.sql.shuffle.partitions
默认值200(Spark 3.x 仍为 200)
经验值单个 shuffle 分区处理 100-200MB 数据
估算方式总 shuffle 数据量除以 200MB 后取整
运行时合并开启 AQE 后由 coalescePartitions 自动合并小分区
读入并行度由文件切分参数决定,与 shuffle 分区数是两回事
写入前收敛repartition 会走 shuffle,coalesce 只减少分区不洗牌

典型使用场景

  • 大表 join 后单分区过大、长尾明显:提高 shuffle 分区数把数据摊开
  • 小数据量作业仍按默认 200 分区跑:产生大量小文件,应调低或交给 AQE 合并
  • 写入 Hive 或湖表前按分区列 repartition,让输出文件数可控
  • 读取一批小文件时并行 task 过多:通过文件切分相关参数把多个小文件合并进一个读分区
  • 任务在同一份数据上时快时慢:先看分区大小分布,再判断是倾斜还是并行度不足

并行度调参示例

并行度调参示例
spark.conf.set('spark.sql.shuffle.partitions', '400')  # 按数据量估算:总量除以 200MB
spark.conf.set('spark.sql.adaptive.enabled', 'true')   # 打开 AQE
spark.conf.set('spark.sql.adaptive.coalescePartitions.enabled', 'true')
spark.conf.set('spark.sql.files.maxPartitionBytes', '134217728')  # 读入阶段单分区 128MB

df = spark.sql("SELECT store_id, sum(pay_amt) AS amt FROM dwd_trade_order_di WHERE dt='2026-10-12' GROUP BY store_id")
df.repartition(64, 'store_id')   # 写入前重分布,控制落盘文件数量
df.write.mode('overwrite').insertInto('dws_trade_store_day')  # 目标表按 store_id 分桶/分区时更均匀

df.coalesce(8)                   # 只减少分区,不触发 shuffle,适合小结果集

相关参数对照

参数作用典型取值
spark.sql.shuffle.partitionsshuffle 后分区数按单分区 100-200MB 估算
spark.sql.adaptive.enabled是否开启自适应执行true
spark.sql.adaptive.coalescePartitions.enabled运行时合并小分区true
spark.sql.files.maxPartitionBytes读入阶段单个分区的数据量128MB(默认)
shuffle 分区数与读入并行度是两个不同的开关:前者只影响 join、group by 之后的阶段,后者由文件切分参数决定。调错对象时现象往往是「参数改了但任务没有任何变化」。
分区数调大并不总是更快。当每个分区只有几 MB 数据时,task 调度与文件打开开销会超过并行带来的收益,这也是 AQE 自动合并小分区被广泛开启的原因。

易错点

  • 并行度设置过大:任务数、输出文件数双双膨胀,调度与小文件开销拖慢整条链路
  • 分区数过小:单 task 数据量过大导致内存溢出,或长尾 task 拖住整体完成时间
  • 不看数据量照搬经验值:小集群上固定 400 反而让调度成为瓶颈
  • 写入前不做收敛:每个分区都输出一批小文件,下游查询与元数据操作明显变慢
  • 把 shuffle 分区参数当读并行度用:改了半天,扫描阶段的 task 数纹丝不动

数据来源与参考

  • Apache Spark 官方文档:Performance Tuning
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌