为什么组合器输出记录=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

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

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

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

来自Hadoop YDN 教程

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

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

Mapper1发射:

hi 1
hello 1
hi 1
hi 1
hello 1

Mapper2发射:

hello 1
hi 1

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

组合器1发射:

hi 3
hello 2

组合器2发射:

hello 1
hi 1

请注意组合器没有更改键。现在,在减速器上,你会得到这样的值:

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

因为您只有一个reducer,所以这次将通过给同一个reductor一个不同的键来再次调用它。

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

最终输出如下

hello 3
hi 4

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

相关内容

  • 没有找到相关文章