我有多输入,所以我有两个映射器。我也有一个合并器:
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;没有减少的输入。我不明白为什么。如果你有想法请做一些解释)) 感谢
答案 0 :(得分:0)
只有拥有减速器才能执行合并器。尝试将组合器和减速器设置为同一类(如果可能),并考虑设置减少任务的数量。
更新:您正在尝试更改合并器中的密钥。组合器的目的是在本地将相同键的值组合在一起以减少流量。
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
输出根据映射器发出的键进行排序。 您可以选择更改缩减器发出的键,但输出不会按缩减器发出的键(默认情况下)排序。希望有所帮助。