PySpark通过spark-submit运行时出现ModuleNotFoundError问题排查
PySpark ETL脚本执行报错排查
我有一个基于PySpark编写的ETL代码,使用两个Bash脚本运行。第一个脚本可正常执行,内容如下:
#!/bin/bash cd /root/Desktop/project rm etl.zip zip -r ./etl.zip * -x logs/\* /u01/spark/bin/spark-submit --conf spark.driver.host=x.x.x.x --conf spark.driver.memory=28g --conf spark.executor.memory=24g --conf spark.rpc.message.maxSize=1024 --conf spark.rpc.askTimeout=600s --conf spark.sql.broadcastTimeout=36000 --driver-class-path ojdbc8.jar --files config.json,basic_tables_config.json --py-files etl.zip project_main.py
但第二个脚本执行时出现ModuleNotFoundError,提示找不到某个Python文件,第二个脚本内容如下:
#!/bin/bash cd /root/Desktop/project rm etl.zip zip -r ./etl.zip * -x logs/\* /u01/spark/bin/spark-submit --conf spark.driver.host=x.x.x.x --conf spark.driver.memory=28g --conf spark.executor.memory=24g --driver-class-path ojdbc8.jar --files config.json,basic_tables_config.json --py-files etl.zip project_main.py
两个脚本的差异是第一个多了以下Spark配置参数:
--conf spark.rpc.message.maxSize=1024 --conf spark.rpc.askTimeout=600s --conf spark.sql.broadcastTimeout=36000
问题分析与解决
缺失的RPC配置和ModuleNotFoundError没有直接因果关系,但结合场景,可能的原因及排查方案如下:
- 压缩包内容不一致:虽然两个脚本的打包命令相同,但第二个脚本执行时,目标Python文件可能处于被占用状态(比如之前的Spark进程未完全退出),导致
zip命令未将其加入etl.zip。手动解压两个脚本生成的压缩包,对比文件列表,确认报错的模块是否存在。 - 执行环境差异:第一个脚本可能在执行前加载了特定的
PYTHONPATH或Python环境(比如conda虚拟环境),第二个脚本运行时环境变量未正确继承。在两个脚本的cd命令后添加echo $PYTHONPATH,对比输出结果是否一致。 - RPC参数间接影响:当你的依赖模块体积较大时,默认的
spark.rpc.message.maxSize(默认128MB)可能不足以传输模块文件,导致Executor端无法完整接收依赖包,最终触发ModuleNotFoundError。这种情况下,添加第一个脚本中的RPC参数即可解决问题。
排查步骤建议:
- 先将第一个脚本的RPC配置参数复制到第二个脚本中,测试是否能正常运行。
- 若问题依旧,手动检查两个脚本生成的
etl.zip内容,确认缺失模块是否存在。 - 对比两个脚本执行时的环境变量,确保
PYTHONPATH、SPARK_HOME等关键变量一致。
内容的提问来源于stack exchange,提问作者M_Gh
相关产品推荐
相关产品推荐

