为什么组合器输出记录 = 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 任务的数量。
更新:您正在尝试更改组合器中的密钥。组合器的目的是在本地将相同键的值组合在一起以减少流量。
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 发出的键排序(默认情况下)。希望对您有所帮助。
我有多个输入,所以我有两个映射器。我还有一个组合器:
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 任务的数量。
更新:您正在尝试更改组合器中的密钥。组合器的目的是在本地将相同键的值组合在一起以减少流量。
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 发出的键排序(默认情况下)。希望对您有所帮助。