PySpark执行write_parquet写入Parquet时触发Py4JJavaError报错求助
问题背景
运行PySpark作业写入Parquet文件时触发报错,核心错误信息如下:
Py4JJavaError: An error occurred while calling o148.parquet. : org.apache.spark.SparkException: Job aborted.
触发错误的代码行:
# Send to .parquet write_parquet(df, config.source_path)
当前环境依赖版本:
findspark 2.0.1 mlflow 1.27 pip 21.2.4 py4j 0.10.9 pylib 1.0.11 pyspark 3.1.2 python 3.7.13 boto3 1.24.19
Java运行时版本:1.8.0_321
诱因分析
- 首先排除核心组件版本硬不匹配问题:PySpark 3.1.2官方绑定的py4j版本就是0.10.9,兼容Python 3.7、Java 8,基础运行时版本组合符合官方兼容要求,之前怀疑的核心组件版本不匹配不成立。
- 外层
Py4JJavaError只是JVM侧任务失败透传到Python端的通用报错,Job aborted是任务级失败的泛化提示,具体根因需要看日志中Caused by字段的完整栈信息,结合环境判断高概率触发原因有以下几类:- 写入路径异常:如果目标路径是本地路径,可能是运行用户对目标目录无读写权限、磁盘空间不足;如果是S3等对象存储路径(环境安装了boto3,这类场景占比很高),可能是密钥配置错误、桶权限不足、路径不存在,或者S3 SDK依赖冲突。
- 依赖冲突:PySpark 3.1.2内置的hadoop-aws模块版本为3.2.0,适配的AWS SDK版本对应boto3兼容区间为1.17.x~1.20.x,当前安装的boto3 1.24.19版本超出兼容范围,很容易触发S3写入时的方法找不到、类加载错误,直接导致任务失败。
- 数据异常:DataFrame中存在Parquet不支持的自定义对象类型、分区字段包含空值或非法特殊字符,写入时序列化失败。
- 资源不足:Executor内存溢出、临时写入目录空间不够,导致任务中途退出。
解决建议
- 先定位具体根因:不要只看最外层的两行报错,翻找Spark Driver/Executor日志中
Job aborted下方的Caused by栈信息,直接定位具体错误点。如果是权限问题直接补目录权限、修正S3密钥配置即可;如果是数据类型问题,提前做字段类型转换、过滤非法值。 - 修复S3依赖兼容问题:执行命令将boto3降级到兼容版本:
pip install boto3==1.20.106
如果提交作业时需要加载hadoop-aws依赖,指定和Spark版本匹配的包即可:
pyspark --packages org.apache.hadoop:hadoop-aws:3.2.0
- 写入前做基础校验:先调用
df.printSchema()确认所有字段都是Spark SQL支持的原生类型,没有混入无法序列化的Python自定义对象;测试阶段可以先写入本地临时路径、用小批量数据验证逻辑:
# 小批量测试写入本地路径,排除路径、依赖问题 df.limit(10).coalesce(1).write.mode("overwrite").parquet("/tmp/test_parquet_write")
- 资源配置调整:如果日志提示内存溢出,适当调大Executor内存配置,将Spark临时目录设置到剩余空间充足的磁盘分区,避免临时文件写满导致任务中断。
内容的提问来源于stack exchange,提问作者h354
相关产品推荐
相关产品推荐

