Apache Spark Glue Job写入S3 Parquet性能过慢,寻求优化方案
Spark Glue Job写入S3 Parquet性能优化方案
针对你遇到的写入性能慢问题,结合你的代码和环境配置,提供以下优化方案:
修正分区策略,减少小文件数量
你当前先执行repartition(10)再partitionBy("some column"),会导致每个分区目录下生成10个仅8MB的小文件,250个分区总计2500个小文件。大量小文件写入S3会产生频繁的HTTP请求,严重拖慢速度。建议:- 直接按分区列+目标文件数重分区:
my_df.repartition(col("some column"), 20).write.partitionBy("some column")...,让每个分区列值对应少量大文件(比如每个文件128MB左右,根据总数据量计算合适的分区数)。 - 或者设置
spark.sql.files.maxRecordsPerFile参数,控制每个文件的记录数,例如:spark.conf.set("spark.sql.files.maxRecordsPerFile", 1000000) # 根据数据大小调整,确保生成128MB左右的文件
- 直接按分区列+目标文件数重分区:
修正分区覆盖模式的配置拼写
你当前配置的shark.sql.sourcess.partitionOverwriteMode存在拼写错误,正确的参数是spark.sql.sources.partitionOverwriteMode,错误的配置可能导致动态覆盖逻辑异常,增加额外开销:spark.conf.set("spark.sql.sources.partitionOverwriteMode", "dynamic")启用Parquet压缩,减少数据传输量
开启Snappy压缩可以大幅降低Parquet文件体积,减少写入S3的数据量,提升速度:spark.conf.set("spark.sql.parquet.compression.codec", "snappy")优化Glue Worker配置与Spark参数
- 选择更高规格的Worker类型:比如将G.1X Worker换成G.2X,每个Worker拥有更多CPU和内存,减少任务调度开销。
- 启用Spark动态分配:允许Spark根据任务负载自动调整Executor数量,避免资源浪费或不足:
spark.conf.set("spark.dynamicAllocation.enabled", "true") spark.conf.set("spark.dynamicAllocation.minExecutors", 5) spark.conf.set("spark.dynamicAllocation.maxExecutors", 20)
使用Glue原生API优化写入
尝试将Spark DataFrame转换为Glue DynamicFrame,利用Glue针对S3和Parquet的优化逻辑,自动调整文件大小和分区策略:from awsglue.dynamicframe import DynamicFrame dynamic_df = DynamicFrame.fromDF(my_df, glueContext, "dynamic_df") dynamic_df.write.partitionBy("some column").mode("overwrite").parquet("s3://...")评估分区列的合理性
250个分区如果超出业务需求,可考虑合并分区(比如将日分区改为周/月分区),减少目录创建和元数据管理的开销,提升写入效率。
内容的提问来源于stack exchange,提问作者Peter Burkert
相关产品推荐
相关产品推荐

