我有一个 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
根据我的理解,这应该把两者main.py
and lib.py
进入分布式缓存文件夹在每台计算机上,从而制作模块lib
有空main
。但这并没有发生:从日志中我看到该文件真的被复制了到同一目录,但是main
无法导入lib
, 投掷ImportError
.
为什么会发生这种情况以及如何解决它?
UPD.将当前目录添加到路径不起作用:
import sys
sys.path.append(os.path.realpath(__file__))
import lib
# ImportError
不过,手动加载模块可以解决问题:
import imp
lib = imp.load_source('lib', 'lib.py')
但这不是我想要的。那么为什么Python解释器会看到其他的.py
文件在同一目录中,但无法导入?请注意,我已经尝试添加一个空的__init__.py
文件复制到同一目录下无效。
我将问题发布到Hadoop用户列表,终于找到了答案。事实证明,Hadoop 并没有真正将文件复制到命令运行的位置,而是创建symlinks对于他们来说。反过来,Python 无法使用符号链接,因此无法识别lib.py
作为Python模块。
Simple 解决方法这是把两者都放在main.py
and lib.py
进入同一目录,这样目录的符号链接被放置到 MR 作业工作目录中,而两个文件物理上位于同一目录中。所以我做了以下事情:
- Put
main.py
and lib.py
into app
目录。
-
In main.py
I used lib.py
直接导入字符串即可
导入库
已上传app
目录与-files
选项。
所以,最终命令如下所示:
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)