为什么组合器输出记录= 0?

时间:2016-04-16 23:32:32

标签: java hadoop mapreduce combiners bigdata

我有多输入,所以我有两个映射器。我也有一个合并器:

class JoinCombiner extends MapReduceBase implements
        Reducer<TextPair, Text, TextPair, Text> {

    @Override
    public void reduce(TextPair key, Iterator<Text> values,
            OutputCollector<TextPair, Text> output, Reporter reporter)
            throws IOException {

        Text nodeId = new Text(values.next());
        while (values.hasNext()) {
            Text node = values.next();
            TextPair outValue = new TextPair(nodeId.toString(), "0");
            output.collect(outValue , node);
        }
    }
}

当我使用这个类作为Reducer时 - 所有单词都很好。但如果我用它作为组合器 - 我在日志中有这个信息:

Combine input records=6
Combine output records=0
Reduce input groups=0
Reduce shuffle bytes=30
Reduce input records=0
Reduce output records=0

因此,没有来自组合器的输出 - &gt;没有减少的输入。我不明白为什么。如果你有想法请做一些解释)) 感谢

1 个答案:

答案 0 :(得分:0)

只有拥有减速器才能执行合并器。尝试将组合器和减速器设置为同一类(如果可能),并考虑设置减少任务的数量。

更新:您正在尝试更改合并器中的密钥。组合器的目的是在本地将相同键的值组合在一起以减少流量。

来自Hadoop Tutorial on YDN

  

Combiner类的实例在已运行map任务的每个节点上运行。组合器将接收Mapper实例在给定节点上发出的所有数据作为输入。然后将Combiner的输出发送到Reducers,而不是Mappers的输出。

根据我的经验,这并非完全正确。 Hadoop只将映射器发出的密钥发送到reducer - 这意味着如果你之间有一个组合器,它应该发出与映射器相同的密钥,减少与密钥相关的值的数量。 IMO,更改组合器中的键会导致意外行为。为了让您理解组合器的简单用法,请考虑使用单词计数器。

Mapper1发出:

hi 1
hello 1
hi 1
hi 1
hello 1

Mapper2发出:

hello 1
hi 1

您有七个输出记录。现在,如果你想在本地减少键的数量(意味着在运行映射器的同一台机器上),那么使用组合器会给你这样的东西:

Combiner1发出:

hi 3
hello 2

Combiner2发出:

hello 1
hi 1

请注意,合并器未更改密钥。现在,在reducer中,您将得到如下值:

Reducer1:key: hi, values: <3, 1>并发出hi 4

因为你只有一个减速器,所以这次会给它一个不同的键再次调用相同的减速器。

Reducer1:key: hello, values: <2, 1>并发出hello 3

最终输出如下

hello 3
hi 4

输出根据映射器发出的键进行排序。 您可以选择更改缩减器发出的键,但输出不会按缩减器发出的键(默认情况下)排序。希望有所帮助。