2011-05-04 203 views
4

我有用Python编写的mapreduce作业。该程序在linux环境下测试成功,但在Hadoop下运行时失败。Hadoop Streaming作业在python中失败

这里是作业命令:

hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-0.20.1+169.127-streaming.jar \ 
    -input /data/omni/20110115/exp6-10122 -output /home/yan/visitorpy.out \ 
    -mapper SessionMap.py -reducer SessionRed.py -file SessionMap.py \ 
    -file SessionRed.py 

会话的模式*的.py是755,和#!/usr/bin/env python是在* .py文件的第一行。 Mapper.py是:从日志

#!/usr/bin/env python 
import sys 
for line in sys.stdin: 
     val=line.split("\t") 
     (visidH,visidL,sessionID)=(val[4],val[5],val[108]) 
     print "%s%s\t%s" % (visidH,visidL,sessionID) 

错误:

java.io.IOException: Broken pipe 
    at java.io.FileOutputStream.writeBytes(Native Method) 
    at java.io.FileOutputStream.write(FileOutputStream.java:260) 
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105) 
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) 
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:109) 
    at java.io.DataOutputStream.write(DataOutputStream.java:90) 
    at org.apache.hadoop.streaming.io.TextInputWriter.writeUTF8(TextInputWriter.java:72) 
    at org.apache.hadoop.streaming.io.TextInputWriter.writeValue(TextInputWriter.java:51) 
    at org.apache.hadoop.streaming.PipeMapper.map(PipeMapper.java:110) 
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50) 
    at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36) 
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:358) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:307) 
    at org.apache.hadoop.mapred.Child.main(Child.java:170) 
    at org.apache.hadoop.streaming.PipeMapper.map(PipeMapper.java:126) 
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50) 
    at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36) 
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:358) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:307) 
    at org.apache.hadoop.mapred.Child.main(Child.java:170) 

回答

0

的Python + Hadoop是在一些细节上,不应该会非常棘手。看看here

尝试用双引号括住输入路径。 (-input“/ data/omni/20110115/exp6-10122”)

1

最后我修复了这个bug,这里是我学到的教训。 1)原始代码没有对错误数据进行错误处理。当我在小数据集上测试代码时,我没有发现问题。 2)为了处理空的字段/变量,我发现在Python中测试None和空字符串有点棘手。我个人喜欢函数len(strVar),它易于阅读和有效。 3)在这种情况下,hadoop命令是正确的。不知怎的,模式644中的* .py可以在我使用的环境中成功运行。

+0

如果你认为这回答了这个问题,你应该选择它作为答案。这将使其他可能面临类似问题的人更容易。 – Kasisnu 2014-01-22 16:47:16

2

您可以在hadoop web界面中找到python错误消息(例如traceback)和脚本写入stderr的其他内容。它有点隐藏,但是您会在流媒体为您提供的链接中找到它。你点击“地图”或“减少”,然后单击任何任务,然后在任务栏上的日志“全部”

1

Hadoop的流 - Hadoop的1.0.x的

我有同样的“管道中断“问题。问题是我的减速器中有一个“休息”声明。所以,一切都顺利,直到“休息”。之后,运行减速器停止运行,打印“Broken pipe”错误。此外,另一个减速器开始运行,与前一个命运相同。这个圈子一直在继续。

如果我理解正确,当reducer从stdin(这是我的情况,在for循环)开始读取时,它必须读取所有内容。即使关闭stdin(我尝试使用os.close(0)),也不能“中断”此操作。

1

我今天玩Hadoop 1.0.1时遇到同样的问题。

的Hadoop ... -mapper $ CWD/mapper.py -reducer $ CWD/reducer.py ...

(我的Python脚本是在当前目录中):幸运的是,我已经解决了它。 现在看起来绝对路径是必需的。

最好!

0

一个可能的解决方案,包括“蟒蛇”,即:

-mapper "python ./mapper.py" 
-reducer "python ./reducer.py" 
3

我得到了同样的问题,不知道是因为当我测试的测试数据我映射器,减速运行它。但是当我通过hadoop map-reduce运行相同的测试集时,我曾经遇到同样的问题。

如何在本地测试代码:

cat <test file> | python mapper.py | sort | python reducer.py 

在更多的研究,我发现,我并没有包括在我的mapper.py脚本中的“家当线”。

#!/usr/bin/python 

请将上面的行添加为您的python脚本的第一行并在此之后留空行。

如果您需要了解更多关于“认领线”,请仔细阅读Why do people write #!/usr/bin/env python on the first line of a Python script?

1

脏的输入可能导致此问题。

尝试使用try {}来避免这种情况。

#!/usr/bin/env python 
import sys 
for line in sys.stdin: 
    try: 
     val=line.split("\t") 
     (visidH,visidL,sessionID)=(val[4],val[5],val[108]) 
     print "%s%s\t%s" % (visidH,visidL,sessionID) 
    except Exception as e: 
     pass