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

31moq8wy  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(471)

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

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

当我用这个类作为减缩-所有的话都很好。但如果我把它用作合并器-我在日志中有这样的信息:

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没有输入。我不明白为什么。如果你有什么想法,请解释一下。谢谢

fhity93d

fhity93d1#

只有在有减速机的情况下,合并器才会被执行。尝试将combiner和reducer都设置为同一类(如果可能的话),同时考虑设置reduce任务的数量。
更新:您正在尝试更改combiner中的密钥。合并器的目的是将同一密钥的值本地分组,以减少通信量。
来自关于ydn的hadoop教程
combiner类的示例在运行map任务的每个节点上运行。组合器将接收给定节点上Map器示例发出的所有数据作为输入。组合器的输出随后被发送到减速器,而不是Map器的输出。
根据我的经验,这不是完全正确的。hadoop只将Map器发出的键发送到reducer,这意味着如果在这两者之间有一个组合器,它应该发出与Map器相同的键,从而减少与该键关联的值的数量。在imo中,更改组合器中的键会导致意外行为。为了让您理解合并器的一个简单用例,请考虑一个单词计数器。
Map器1发射:

hi 1
hello 1
hi 1
hi 1
hello 1

mapper2发射:

hello 1
hi 1

你有七个输出记录。现在,如果您想在本地减少密钥的数量(意味着在Map程序运行的同一台机器上),那么拥有一个组合器会给您带来如下结果:
合路器1发射:

hi 3
hello 2

combiner2发射:

hello 1
hi 1

请注意,combiner没有更改键。现在,在减速器处,您将得到如下值:
减速器1: key: hi, values: <3, 1> 然后你就会发出 hi 4 因为只有一个减速机,所以这次将通过给它一个不同的键来再次调用同一个减速机。
减速器1: key: hello, values: <2, 1> 然后你就会发出 hello 3 最终输出如下

hello 3
hi 4

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

相关问题