我在中定义了MapReduce作业main.py
,该作业从中导入lib
模块lib.py
。我使用Hadoop流将作业提交到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
并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并没有真正将文件复制到命令运行的位置,而是为其创建了符号链接。反过来,Python无法使用符号链接,因此无法识别lib.py
为Python模块。
简单的解决方法在这里是把两者main.py
并lib.py
到同一个目录,使符号链接的目录放置到MR工作的工作目录,而这两个文件是物理上在同一个目录。所以我做了以下事情:
main.py
与lib.py
入app
目录。在main.py
我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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句