在hadoop流中读取文件

时间:2016-03-14 02:12:01

标签: hadoop mapreduce

我正在尝试在我的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():

1 个答案:

答案 0 :(得分:0)

您获得的错误意味着您的映射器无法长时间写入stdout流。

例如,错误的常见原因是在do_something()函数中,您有一个for循环,其中包含具有特定条件的continue语句。然后,当您的输入数据中经常出现这种情况时,您的脚本会连续多次连续运行,而不会向stdout生成任何输出。 <{1}}在没有看到任何内容的情况下等待太久,因此该任务被视为失败。

另一种可能性是输入数据文件太大,读取时间太长。但我认为这是设置时间,因为它在第一行输出之前。我不确定。

有两种相对简单的方法可以解决这个问题:

  1. (开发人员方面)修改代码,不时地输出内容。在继续的情况下,写一个简短的虚拟符号,如Hadoop,让'\n'知道你的脚本是活着的。

  2. (系统方面)我相信您可以使用Hadoop选项设置以下参数,该选项控制以毫秒为单位的等待时间

    mapreduce.reduce.shuffle.read.timeout

  3. 我从未尝试过选项2.通常我会避免对需要过滤的数据进行流式处理。流式传输,尤其是使用像-D这样的脚本语言完成时,应该尽可能少地工作。我的用例主要是来自Python的后处理输出数据,其中已经在Apache Pig脚本中进行了过滤,我需要Pig中没有的内容。