我的映射器(Hadoop 1.2.1)创建了令牌的键值对,我从一个简单的文本文件中读取。没有火箭科学。 reducer最终“捆绑”(在Hadoop中,你是否像在SQL中一样调用分组?)相同的键并且还将值1加起来。这是默认的Hadoop教程。
但是,当我的reducer可以使用这些值时,我希望将所有值降序排序。仅显示前30个标记(字符串,单词)。
似乎有些概念对我来说并不清楚。
reduce
方法,对吧?因此,我没有看到缓冲HashMap之类的地方,它可以保存最高结果(最常见的令牌)。 我在想,如果我有这样一个变量,我可以很容易地比较并插入每个具有前30个值的键。处理这个频率排名任务的适当方法是什么?
public static class Reduce extends MapReduceBase implements
Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterator<IntWritable> values,
OutputCollector<Text, IntWritable> output, Reporter reporter)
throws IOException {
int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
// CURRENTLY I SIMPLY OUTPUT THE KEY AND THE SUM.
// IN THIS PLACE, HOW COULD YOU STORE E.G. A HASHMAP THAT
// COULD STORE THE TOP 30?
output.collect(key, new IntWritable(sum));
LOG.info("REDUCE: added to output:: key: " + key.toString());
}
}
答案 0 :(得分:1)
首先,为每个键值对调用reduce方法,对吧? 因此,我没有看到像HashMap这样的缓冲区的地方 可以保持最佳结果(最常见的代币)。
有点细微差别:reduce
方法每个键运行一次,而不是键值对。具有该密钥的每个值都显示在Iterator
中。如果要存储HashMap
,可以在setup
函数中设置它(或使其成为私有对象),在reduce函数中与它进行交互,然后在其中执行任何操作。 cleanup
功能。因此,在reduce
的调用中保持状态肯定是可能的。
但是,我认为您可能会以更聪明的方式解决您的问题。我曾经多次写过十大名单,只是因为我觉得它们很有趣,而且它们是非常有用的工具。我希望前30名与前10名有什么关系。
Here is an example of a top-ten list generator我写了一段时间,可以适应你的问题。
您可以稍微改变一下如何解决问题以适应这种模式。在我的代码中,我使用的是TreeMap
而不是HashMap
,因为TreeMap
会按顺序排列。一旦你得到31个项目,请弹出频率最低的项目。
我还讨论了MapReduce设计模式一书中的前十大模式(抱歉无耻的插件)。