You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark Parquet写入文件数量与内存分区数不符的原因咨询

PySpark Parquet写入文件数量规则及异常现象解析

一、核心规则

PySpark写入Parquet时,文件数的基础逻辑:

  • 非空内存分区数直接对应输出文件数,每个非空分区生成一个文件。
  • 以下情况会打破这个对应关系:
    • 分区无数据:空分区不会生成文件
    • 写入过程中触发了隐式的分区合并(如小文件合并优化)
    • 使用partitionBy指定目录分区时,每个子目录下的文件数由该目录对应的数据分区数决定
    • 按列重分区时,列的基数限制了实际有效分区数

二、你的测试现象拆解

1. 无指定列的repartition(200)

调用repartition(200)不指定列时,Spark用随机哈希拆分数据:
10万条数据被均匀分配到200个分区,每个分区约500条数据,没有空分区。写入时每个分区对应一个文件,所以生成200个文件,完全符合预期。

2. 指定列repartition(200, 'a')的异常原因

按列a重分区时,Spark会根据a的哈希值分配数据:

  • 如果列a的不同取值(基数)只有11个,那么所有相同a值的数据都会被分到同一个分区——不管你指定多少个目标分区数(200),最终只有11个非空分区。
  • 空分区不会生成文件,所以最终只输出11个Parquet文件。

你可以用这段代码验证列a的基数:

dummy_data.select('a').distinct().count()

结果肯定是11,完全对应你的输出文件数。

三、额外提示

  • 按列重分区时,如果列的基数远小于指定的分区数,必然会出现大量空分区,导致文件数远低于预期。
  • 如果需要按列分区同时保证文件数量,可以先按列分区,再做一次随机重分区:
dummy_data.repartition('a').repartition(200)

或者针对Hive场景使用bucketBy来更均衡地拆分数据。

内容的提问来源于stack exchange,提问作者figs_and_nuts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:16:06