我正在尝试在我的mapper中读取一个辅助文件,这是我的代码和命令。
映射器代码:
#!/usr/bin/env python
from itertools import combinations
from operator import itemgetter
import sys
storage = {}
with open('inputData', 'r') as inputFile:
for line in inputFile:
first, second = line.split()
storage[(first, second)] = 0
for line in sys.stdin:
do_something()
这是我的命令:
hadoop jar hadoop-streaming-2.7.1.jar \
-D stream.num.map.output.key.fields=2 \
-D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator \
-D mapred.text.key.comparator.options='-k1,1 -k2,2' \
-D mapred.map.tasks=20 \
-D mapred.reduce.tasks=10 \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-mapper mapper.py -file mapper.py \
-reducer reducer.py -file reducer.py \
-file inputData \
-input /data \
-output /result
但是我一直收到这个错误,这表明我的mapper无法从stdin读取。删除读取文件部分后,我的代码工作,所以我已经指出了发生错误的地方,但我不知道应该从哪里读取它的正确方法。有人可以帮忙吗?
Error: java.lang.RuntimeException: PipeMapRed.waitOutputThreads():
答案 0 :(得分:0)
您获得的错误意味着您的映射器无法长时间写入stdout
流。
例如,错误的常见原因是在do_something()
函数中,您有一个for循环,其中包含具有特定条件的continue
语句。然后,当您的输入数据中经常出现这种情况时,您的脚本会连续多次连续运行,而不会向stdout
生成任何输出。 <{1}}在没有看到任何内容的情况下等待太久,因此该任务被视为失败。
另一种可能性是输入数据文件太大,读取时间太长。但我认为这是设置时间,因为它在第一行输出之前。我不确定。
有两种相对简单的方法可以解决这个问题:
(开发人员方面)修改代码,不时地输出内容。在继续的情况下,写一个简短的虚拟符号,如Hadoop
,让'\n'
知道你的脚本是活着的。
(系统方面)我相信您可以使用Hadoop
选项设置以下参数,该选项控制以毫秒为单位的等待时间
mapreduce.reduce.shuffle.read.timeout
我从未尝试过选项2.通常我会避免对需要过滤的数据进行流式处理。流式传输,尤其是使用像-D
这样的脚本语言完成时,应该尽可能少地工作。我的用例主要是来自Python
的后处理输出数据,其中已经在Apache Pig
脚本中进行了过滤,我需要Pig
中没有的内容。