如何在亚马逊弹性MapReduce (EMR) 中导入本地Python包?

1 投票
2 回答
1708 浏览
提问于 2025-04-18 14:42

我有两个Python脚本,打算在亚马逊的弹性MapReduce上运行,一个是映射器(mapper),一个是归约器(reducer)。最近我扩展了映射器的脚本,需要用到我自己创建的几个本地模型,这些模型都在一个叫做SentimentAnalysis的包里。请问,怎么才能让Python脚本从S3上的本地Python包中导入呢?我试着在S3上创建了一些和我的文件系统相似的键,希望能用相对路径,但结果并不如意。以下是我在S3的日志文件中看到的内容,步骤失败后记录的:

Traceback (most recent call last):
File "/mnt/var/lib/hadoop/mapred/taskTracker/hadoop/jobcache/job_201407250000_0001/attempt_201407250000_0001_m_000000_0/work/./sa_mapper.py", line 15, in <module>
from SentimentAnalysis import NB, LR
ImportError: No module named SentimentAnalysis

相关的文件结构是这样的:

sa_mapper.py
sa_reducer.py
SentimentAnalysis/NB.py
SentimentAnalysis/LR.py

而mapper.py的内容是:

from SentimentAnalysis import NB, LR

我试着在S3上复制文件结构,但似乎不太奏效。

有没有什么好的方法来设置S3或EMR,让sa_mapper.py能够导入NB.py和LR.py?这其中有没有什么特别的技巧呢?

2 个回答

0

你正在运行的命令是什么?
要做到这一点,唯一的方法是,当你想要运行一个步骤时,你可以添加一些额外的字段到这个步骤中。例如:如果你使用的是boto这个包来在emr上运行任务,你会用到一个叫做StreamingStep的类。

在这个类里,你会看到一些参数(如果你使用的是2.43版本):
cache_files(列表)– 一组需要和任务一起打包的缓存文件
cache_archives(列表)– 一组需要和任务一起打包的jar归档文件

这意味着你需要传递你想从s3中取到的文件夹的路径到你的集群中。语法是:
s3://{s3 bucket path}/EMR_Config.py#EMR_Config.py
在这里,井号(#)是分隔符,井号前面的部分是你在s3中的位置,井号后面的部分是你希望它拥有的名称和位置,目前它会和你正在运行的任务放在同一个地方。

一旦你把它们放到你的集群中,你不能简单地使用import,
有效的方法是:

# we added a file named EMR_Config.py, 
sys.path.append(".")

#loading the module this way because of the EMR file system
module_name = 'EMR_Config'
__import__(module_name)
Config = sys.modules[module_name]

#now you can access the methods in the file, for example:
topic_name = Config.clean_key(row.get("Topic"))
0

你在情感分析的文件夹里有

__init__.py

吗?

撰写回答