ffr*_*end 10 python mapreduce hadoop-streaming
我定义了一个MapReduce作业main.py
,从中导入lib
模块lib.py
.我使用Hadoop Streaming将此作业提交到Hadoop集群,如下所示:
hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar -files lib.py,main.py
-mapper "./main.py map" -reducer "./main.py reduce"
-input input -output output
Run Code Online (Sandbox Code Playgroud)
在我的理解,这应该把两者main.py
并lib.py
进入分布式缓存文件夹中的每个计算设备上,从而使模块lib
可用main
.但它没有发生:从日志中我看到文件真的被复制到同一目录,但main
无法导入lib
,抛出ImportError
.
为什么会发生这种情况,我该如何解决?
UPD.将当前目录添加到路径不起作用:
import sys
sys.path.append(os.path.realpath(__file__))
import lib
# ImportError
Run Code Online (Sandbox Code Playgroud)
但是,手动加载模块可以解决问题:
import imp
lib = imp.load_source('lib', 'lib.py')
Run Code Online (Sandbox Code Playgroud)
但这不是我想要的.那么为什么Python解释器会.py
在同一目录中看到其他文件,但却无法导入它们?请注意,我已经尝试将空__init__.py
文件添加到同一目录而不起作用.
ffr*_*end 12
我将问题发布到Hadoop用户列表,最后找到答案.事实证明,Hadoop并不真正将文件复制到命令运行的位置,而是为它们创建符号链接.反过来,Python无法使用符号链接,因此无法识别lib.py
为Python模块.
简单的解决方法在这里是把两者main.py
并lib.py
到同一个目录,使符号链接的目录放置到MR工作的工作目录,而这两个文件是物理上在同一个目录.所以我做了以下事情:
main.py
与lib.py
入app
目录.在main.py
我lib.py
直接使用,即导入字符串只是
导入lib
app
带-files
选项的上传目录.
所以,final命令看起来像这样:
hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar -files app
-mapper "app/main.py map" -reducer "app/main.py reduce"
-input input -output output
Run Code Online (Sandbox Code Playgroud)
小智 5
当 Hadoop-Streaming 启动 python 脚本时,你的 python 脚本的路径就是脚本文件真正所在的位置。但是,hadoop 以 './' 开头,而您的 lib.py(它是一个符号链接)也在 './' 处。因此,在导入 lib.py 之前尝试添加 'sys.path.append("./")',如下所示:
import sys
sys.path.append('./')
import lib
归档时间: |
|
查看次数: |
6526 次 |
最近记录: |