AWS Glue PySpark任务写S3报No space left on device问题求助
问题重现
任务执行Parquet写入操作时抛出磁盘空间不足错误:
Lost task 780.1 in stage 677.0 (TID 150416) (172.36.134.20 executor 16): java.io.IOException: No space left on device
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
触发错误的代码:
df_finance.write.format("parquet").mode('overwrite').save(source_path + "temp/df_finance/")
已尝试方案:设置--write-shuffle-files-to-s3参数、重分区、过滤数据集、合并写入、扩容至G4.X机型149个Worker,均未解决问题。
排查与解决方案
1. 修正--write-shuffle-files-to-s3参数配置
- 该参数仅支持Glue 2.0及以上版本,先确认你的Glue Job版本符合要求。
- 参数需搭配具体S3路径使用,且要放在
--conf参数组中,正确配置格式为:
仅写参数名不指定S3路径不会生效。--conf spark.sql.shuffle.partitions=200 --write-shuffle-files-to-s3 s3://your-bucket/shuffle-storage/
2. 强制Spark临时文件写入S3
除Shuffle文件外,Spark写入Parquet时的中间临时文件也会占用Executor本地磁盘,可通过配置将临时工作目录指向S3:
from pyspark.sql import SparkSession spark = SparkSession.builder \ .config("spark.local.dir", "s3://your-bucket/temp-spark-workdir/") \ .getOrCreate()
3. 优化写入逻辑减少本地磁盘压力
- 控制分区数量:用
repartition或coalesce调整分区数,避免单Executor处理过多数据,同时结合分桶写入降低小文件数量:
之后再将表数据导出到目标S3路径。df_finance.repartition(100) \ .write.format("parquet") \ .mode('overwrite') \ .bucketBy(10, "finance_id") \ .saveAsTable("temp_finance_table") - 启用动态分区覆盖:在Job Parameters中添加
--enable-dynamic-partition-overwrites,减少不必要的分区写入操作。
4. 检查Worker实例磁盘配置
G4.X系列不同实例的本地磁盘空间差异较大,确认是否选用了带足够本地存储的实例(如G4dn.Xlarge带有125GB NVMe磁盘);若使用无本地磁盘的实例,必须强制所有临时文件写入S3。
5. 排查并解决数据倾斜
扩容Worker无法解决数据倾斜问题,单个Executor仍可能因处理远超平均的数据量耗尽磁盘。可通过以下代码检测倾斜Key:
df_finance.groupBy("key_column").count().orderBy(col("count").desc()).show(10)
针对倾斜Key,采用拆分处理、加盐等方式分散数据压力。
内容的提问来源于stack exchange,提问作者Vibhav MS

