首页/数据/数仓建模速查/Spark 输出文件布局控制
湖仓与引擎63 条

Spark 输出文件布局控制

控制输出文件数与大小:partitionBy 控制目录、maxRecordsPerFile 限制单文件行数、repartition 与 coalesce 调整写出并行度。

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

Spark 输出文件布局控制

Spark 写出结果的文件布局由三件事决定:partitionBy 决定目录层级,repartition 或 coalesce 决定写出并行度与文件个数,maxRecordsPerFile 限制单个文件的行数。目标是让单个文件落在 128 到 256MB 区间,避免海量 KB 级小文件拖慢后续查询与元数据操作。

基本信息

目录层级partitionBy
单文件大小maxRecordsPerFile(按行数控制)
写出并行度repartition / coalesce
目标文件大小128 至 256MB
输出格式Parquet / ORC 列式

典型使用场景

  • 常规落表任务:按 dt 分区写出,先按目标文件大小反推写出并行度
  • 数据倾斜:repartition 按分区键重分布,缓解个别任务写出超大文件
  • 小结果集:coalesce 收拢到少量文件,避免每个分区产出空文件
  • 全量重写:控制并行度与文件数,防止一次任务产生数万个小文件
  • 排查小文件:先看写出任务的并行度与分区数,再决定在写入端合并还是只在读取端合并

写出布局

写出布局
spark.conf.set('spark.sql.files.maxRecordsPerFile', 2000000)  # 单文件最多约 200 万行
df = spark.table('dws_trade_store_day').where("dt = '2026-10-12'")
df.repartition(32, 'store_id') \     # 32 个写任务,按门店键重分布缓解倾斜
  .write.mode('overwrite') \
  .partitionBy('dt') \              # 按数据日期分目录
  .parquet('/warehouse/dws/trade_store')
# 小结果集改用 coalesce(2) 收拢文件数,避免每分区产出一个空文件

并行度控制方式对比

方式是否 shuffle适用场景
repartition(n)是,开销较大需要均匀分布文件数
repartition(n, col)是按键重分布缓解倾斜
coalesce(n)否收拢小结果集的文件数
coalesce 不触发 shuffle,但会继承上游分区,上游分布不均时文件大小仍然悬殊;需要均匀分布时要改用 repartition。
用行数控制文件大小只是间接手段,效果取决于单行宽度;先按经验估算单行大小设定参数,跑完一批后看实际落盘大小再回调更靠谱。
写出并行度要跟着数据量走:小数据量用高并行度只会产出大量空文件,大数据量用低并行度则单文件过大、单任务耗时过长。调度脚本里把并行度写成可配置参数,按数据规模滚动调整。
分区写入的数据量跨分区不均匀时,个别分区会产出超大文件或大量小文件;跑完任务后按分区统计文件数与大小分布,比只看总量更能发现问题分区。

易错点

  • 写出不做并行度控制:按默认 shuffle 分区落盘,产生海量 KB 级小文件,后续查询的元数据开销剧增
  • 全量数据用 coalesce(1):单任务写成为瓶颈,任务超时且下游无法并行读
  • 对极小结果集用 repartition 到高并发:产出大量空文件或只有几行的文件
  • 分区键基数极高(如按用户 ID 分区):目录数爆炸,写入与列举都显著变慢

数据来源与参考

  • Apache Spark 官方文档:Configuration
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌