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

Why combiner output records = 0?

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

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);
        }
    }
}

当我将此 class 用作 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

因此,合并器没有输出 -> 没有减少输入。我不明白为什么。如果您有想法,请做出一些解释)) 谢谢

只有当你有一个减速器时,一个组合器才会被执行。尝试将 combiner 和 reducer 设置为相同的 class(如果可能)并考虑设置 reduce 任务的数量。

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

来自Hadoop Tutorial on YDN

Instances of the Combiner class are run on every node that has run map tasks. The Combiner will receive as input all data emitted by the Mapper instances on a given node. The output from the Combiner is then sent to the Reducers, instead of the output from the Mappers.

根据我的经验,这并不完全正确。 Hadoop 仅将映射器发出的键发送到缩减器 - 这意味着如果您在两者之间有一个组合器,它应该发出与映射器相同的键,减少与键关联的值的数量。 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

因为你只有一个 reducer,所以这次给它一个不同的 key 会再次调用同一个 reducer。

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

最终输出结果如下

hello 3
hi 4

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