Hadoop Streaming作业在Python中失败

5 投票
8 回答
15000 浏览
提问于 2025-04-16 17:00

我有一个用Python写的mapreduce任务。这个程序在Linux环境下测试成功,但在Hadoop下运行时失败了。

这是运行这个任务的命令:

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

Session*.py的权限设置为755,文件的第一行是#!/usr/bin/env python。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)

8 个回答

1

最后我修复了这个bug,下面是我学到的一些经验教训。

1) 原来的代码没有处理错误数据的机制。当我在一个小数据集上测试代码时,没有发现这个问题。

2) 处理空字段或变量时,我发现用Python来判断None和空字符串有点棘手。个人来说,我喜欢用len(strVar)这个函数,因为它既简单又有效。

3) 在这种情况下,hadoop命令是正确的。奇怪的是,模式为644的*.py文件在我使用的环境中可以成功运行。

2

你可以在Hadoop的网页界面上找到Python的错误信息(比如说错误追踪信息)以及你的脚本写入的其他内容,这些信息会显示在标准错误输出中。虽然这个地方有点隐藏,但你可以通过流处理提供的链接找到它。你点击“Map”或“Reduce”,然后选择任何一个任务,接着在“任务日志”这一栏里点击“全部”。

5

我也遇到了同样的问题,之前我在测试数据上测试我的映射器和归约器时是可以运行的。但是当我通过Hadoop的MapReduce运行同样的测试集时,我又遇到了同样的问题。

如何在本地测试你的代码:

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

经过进一步调查,我发现我在我的mapper.py脚本中没有包含“shebang行”。

#!/usr/bin/python

请把这一行加到你的Python脚本的第一行,并在这行之后留一个空行。

如果你想了解更多关于“shebang行”的信息,可以阅读 为什么人们在Python脚本的第一行写#!/usr/bin/env python?

撰写回答