我已经实现了一个简单的地图降低了用于检测最长单词的应用程序。该工作成功执行。
但是现在我想知道在还原器中使用局部变量以保持最大长度是否正确?由于分布式环境中可能有多个还原器,并且它们不具有该变量的值。
这是正确的假设吗?
当有独立还原器时,在分布式环境中将如何影响输出?
我使用的是自定义比较器,因此单词首先按长度和值分类。每个MR阶段的输出看起来像这样:
Mapper Output:
ByeByeBye 9
HelloHelloHe222 15
HelloHelloHe222 15
HelloHelloHe333 15
HelloHelloHe333 15
HelloHelloHellw99999 20
Combiner Output:
ByeByeBye 9
HelloHelloHe222 15
HelloHelloHe333 15
HelloHelloHellw99999 20
ComparatorOutput:
HelloHelloHellw99999 20
HelloHelloHe222 15
HelloHelloHe333 15
ByeByeBye 9
Reducer Output:
HelloHelloHellw99999 20
REDUCER类:
public class WordsReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private int maxLength = Integer.MIN_VALUE;
private IntWritable length = new IntWritable();
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
length = values.iterator().next();
if (length.get() >= maxLength){
maxLength = length.get();
context.write(key, length);
}
}
}
首先,我看不到比较器的需求,因为找到最大的最大值不应需要排序的数据集。
查找任何数据集的最大值都是仅MAP的操作。查找多个地图任务的总体最大值需要减少这些单个任务,只能由一个还原器在其具有可用的所有数据的情况下完成。
您的还原代码仅输出每个还原器的最大值。您的钥匙是文本,但是有多个文本,因此没有机会看到总体最大值。您获得一个输出的原因是,组合仪已经将唯一字符串收集到一个项目中,并且这些项目以降序排序。
您需要仅在映射器上输出字符串的最大长度的逻辑,可能会使用Treemap在代币上迭代时存储中间长度,而不是编写迭代的当前最大值。使用字段很好,但是并非所有任务都共享。您将使用计数器对象,这些对象存储在上下文对象中。
如果您希望没有当前代码的组合程序的总最大值,则考虑到第一运行的输出的输入,您将运行两次。想象一下这种情况,还原1的最大长度为15,最大长度为20的缩影2结束。因此,您已经写了两个输出,而不仅仅是总体最大值。
如前所述,每个地图任务都需要编写其各自的最大字符串。然后,您实际上可以使用无效的键,输出null, "length,word"
。然后,在还原器中,您取出所有值,提取长度,找到最大的长度,然后打印