PySpark聚合DataFrame写入S3时如何生成单个Parquet文件?
解决Spark DataFrame写入S3生成单个Parquet文件的问题
Spark写入Parquet文件时,会根据DataFrame的分区数量生成对应数量的文件。你的df2经过分组聚合后,分区数刚好是10,所以才会生成10个文件。要生成单个文件,有以下几种可行方案:
方案1:使用coalesce(1)合并分区
coalesce可以直接减少分区数到1,属于窄依赖操作,不会触发数据shuffle,适合小数据量场景(比如你的10行数据)。修改后的写入代码如下:
df2.coalesce(1).write.mode("overwrite").parquet('s3://path')
方案2:使用repartition(1)重新分区
repartition会触发数据shuffle,将所有数据重新分配到1个分区,同样能生成单个文件。代码示例:
df2.repartition(1).write.mode("overwrite").parquet('s3://path')
注意:这个方法会有shuffle开销,小数据量无所谓,大数据量不建议使用。
方案3:事后合并已生成的多文件
如果已经生成了多个Parquet文件,也可以用AWS CLI手动合并:
# 先下载所有part文件到本地 aws s3 cp s3://path/ ./local_temp/ --recursive --exclude "*" --include "part-*.parquet" # 合并成单个文件 cat ./local_temp/part-*.parquet > merged.parquet # 上传回S3 aws s3 cp merged.parquet s3://target_path/
这种方法不如写入前合并分区高效,仅作为补救方案。
额外提醒
- 只有数据量较小时才适合生成单个Parquet文件,大数据量下单个文件会严重影响读取性能,也无法利用Spark的并行处理能力。
- 如果需要以表格式写入,合并分区后使用
saveAsTable即可:df2.coalesce(1).write.mode("overwrite").saveAsTable("your_database.your_table")
内容的提问来源于stack exchange,提问作者SAI GANESH
相关产品推荐
相关产品推荐

