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
相关产品推荐
相关产品推荐

