PySpark引入外部Python模块方法及AWS EMR运行报错问题问询
PySpark on AWS EMR 导入模块报错解决方案
一、ModuleNotFoundError: No module named 'utils' 修复
1. 不打包解决方案
首先在你的utils目录下新增一个空的__init__.py文件,上传到S3对应的utils路径下,这是Python识别目录为可导入包的必要条件。
提交命令中--py-files参数不支持直接传递目录,需要将包依赖的所有Python文件逐个列出,用逗号分隔,修改后的命令如下:
spark-submit --py-files s3://bucket/utils/__init__.py,s3://bucket/utils/utils1.py,s3://bucket/utils/utils2.py s3://bucket/folder1/main.py
2. 打包解决方案
打包方案更适合依赖文件多的场景,操作步骤如下:
- 在本地进入
utils目录的父级目录,执行打包命令:
注意要将整个zip -r utils.zip utils/utils文件夹(包含__init__.py)打包,不要只打包目录内的单个文件 - 将生成的
utils.zip上传到S3路径,修改提交命令:
Spark会自动将zip包解压到Driver和Executor的工作路径,可直接正常导入spark-submit --py-files s3://bucket/utils.zip s3://bucket/folder1/main.pyutils下的模块。
二、java.io.FileNotFoundException 报错原因
该报错是部分旧版本AWS EMR的已知问题:EMR的command-runner.jar处理spark-submit的--py-files参数时,无法正确解析S3路径的压缩包,会错误将S3路径拼接为节点本地文件系统路径去查找,因此找不到对应文件。
对应修复方案二选一即可:
- 将打包好的
utils.zip提前上传到EMR集群所有节点的相同本地路径,提交命令中--py-files指定该本地路径 - 提交任务前先通过
aws s3 cp命令将S3上的zip包拉取到当前步骤执行节点的本地目录,再将本地路径传递给--py-files参数
内容的提问来源于stack exchange,提问作者Vladimir Shadrin
相关产品推荐
相关产品推荐

