如何在亚马逊弹性MapReduce (EMR) 中导入本地Python包?
我有两个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 个回答
你正在运行的命令是什么?
要做到这一点,唯一的方法是,当你想要运行一个步骤时,你可以添加一些额外的字段到这个步骤中。例如:如果你使用的是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"))
你在情感分析的文件夹里有
__init__.py
吗?