Hadoop Streaming:Mapper'包装'二进制可执行文件

时间:2010-11-06 15:45:23

标签: python binary streaming hadoop mapreduce

我有一个管道,我目前在一个大型大学计算机集群上运行。出于发布目的,我想将其转换为mapreduce格式,以便任何人都可以使用像amazon webservices(AWS)这样的hadoop集群来运行它。该管道目前由一系列python脚本组成,这些脚本包含不同的二进制可执行文件,并使用python子进程和tempfile模块管理输入和输出。不幸的是,我没有编写二进制可执行文件,其中许多不是采用STDIN或不以“可用”方式发出STDOUT(例如,仅将其发送到文件)。这些问题就是我将它们中的大部分包装在python中的原因。

到目前为止,我已经能够修改我的Python代码,以便我有一个mapper和一个reducer,我可以在我的本地机器上以标准的“测试格式”运行。

$ cat data.txt | mapper.py | reducer.py

映射器按照它所包含的二进制文件的方式格式化每一行数据,使用subprocess.popen将文本发送到二进制文件(这也允许我屏蔽很多虚假的STDOUT),然后收集我想要的STOUT,并将其格式化为适合reducer的文本行。 当我尝试在本地hadoop安装上复制命令时出现问题。我可以让mapper执行,但它会给出一个错误,表明它无法找到二进制可执行文件。

  

文件   “/Users/me/Desktop/hadoop-0.21.0/./phyml.py”   第69行,在       main()文件“/Users/me/Desktop/hadoop-0.21.0/./mapper.py”,   第66行,主要       phyml(无)文件“/Users/me/Desktop/hadoop-0.21.0/./mapper.py”,   第46行,在phyml       ft = Popen(cli_parts,stdin = PIPE,stderr = PIPE,stdout = PIPE)文件   “/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py”   第621行,在 init 中       errread,errwrite)文件“/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py”,   第1126行,在_execute_child中       提出child_exception   OSError:[Errno 13]权限被拒绝

我的hadoop命令如下所示:

./bin/hadoop jar /Users/me/Desktop/hadoop-0.21.0/mapred/contrib/streaming/hadoop-0.21.0-streaming.jar \
-input /Users/me/Desktop/Code/AWS/temp/data.txt \
-output /Users/me/Desktop/aws_test \
-mapper  mapper.py \
-reducer  reducer.py \
-file /Users/me/Desktop/Code/AWS/temp/mapper.py \
-file /Users/me/Desktop/Code/AWS/temp/reducer.py \
-file /Users/me/Desktop/Code/AWS/temp/binary

正如我上面提到的,它看起来像mapper不知道二进制文件 - 也许它没有被发送到计算节点?不幸的是我无法确定问题是什么。任何帮助将不胜感激。特别好看的是用python编写的一些用于包装二进制可执行文件的hadoop流映射器/缩减器。我无法想象我是第一个尝试这样做的人!事实上,这是另一篇提出基本相同问题的帖子,但尚未得到回答......

Hadoop/Elastic Map Reduce with binary executable?

2 个答案:

答案 0 :(得分:4)

经过大量谷歌搜索(等)后,我想出了如何包含可由地图制作者/缩减者访问的可执行二进制文件/脚本/模块。诀窍是首先将所有文件上传到hadoop。

$ bin/hadoop dfs -copyFromLocal /local/file/system/module.py module.py

然后您需要格式化您的流命令,如下面的模板:

$ ./bin/hadoop jar /local/file/system/hadoop-0.21.0/mapred/contrib/streaming/hadoop-0.21.0-streaming.jar \
-file /local/file/system/data/data.txt \
-file /local/file/system/mapper.py \
-file /local/file/system/reducer.py \
-cacheFile hdfs://localhost:9000/user/you/module.py#module.py \
-input data.txt \
-output output/ \
-mapper mapper.py \
-reducer reducer.py \
-verbose

如果您要链接python模块,则需要将以下代码添加到mapper / reducer脚本中:

import sys 
sys.path.append('.')
import module

如果您通过子处理访问二进制文件,您的命令应如下所示:

cli = "./binary %s" % (argument)
cli_parts = shlex.split(cli)
mp = Popen(cli_parts, stdin=PIPE, stderr=PIPE, stdout=PIPE)
mp.communicate()[0]

希望这有帮助。

答案 1 :(得分:2)

让它最终运行

$pid = open2 (my $out, my $in, "./binary") or die "could not run open2";