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

当我使用这个类作为 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 没有输出 -> reduce 没有输入。我不明白为什么。如果您有想法,请做出一些解释))谢谢

4

1 回答 1

0

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

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

来自YDN 上的 Hadoop 教程

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

请注意,combiner 没有更改密钥。现在,在 reducer 中,您将获得如下值:

Reducer1:key: hi, values: <3, 1>然后你发出hi 4

因为你只有一个reducer,同一个reducer 将通过这次给它一个不同的key 来再次调用。

Reducer1:key: hello, values: <2, 1>然后你发出hello 3

最终输出如下

hello 3
hi 4

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

于 2016-04-17T07:58:19.593 回答