如何解决MapReduce中的前N个项目
这些是我在MapReduce中的第一步,但是我对如何解决此问题有疑问。我知道这个问题已经在StackOverflow上“解决了”几次,但我尚不完全清楚Map和Reduce步骤之间有什么区别,以及为什么要在Map步骤中进行过滤。
问题
假设您有一个包含名称的大型数据集。您想要检索出现次数最多的前10个名称。
解决方案
我了解MapReduce背后的原理,也了解WordCount示例的作用,但老实说,我有点卡在这里。我已经阅读了一些示例以及此PDF。在伪代码中,他们已经在每个Map步骤中过滤了前K个出现的事件,然后在Reduce步骤中执行了类似的操作。
我第一步基于this example在Java中实现了这一目标。注意:我不一定要100%正确地使用语法,我只需要了解为什么以这种方式实现它即可。
地图
public static class TopTenMapper extends Mapper {
private PriorityQueue<String> values;
private Map<String,Integer> occurrences;
private int maxItems = 10;
public void setup(Context context) {
values = new PriorityQueue<>((n1,n2) -> occurrences.get(n1) - occurrences.get(n2));
occurrences = new HashMap<>();
}
public void map(Object key,Text value,Context context) {
String name = value.toString();
occurrences.put(name,occurrences.getOrDefault(name 0) + 1);
}
public void cleanup(Context context) {
int idx = 0;
for (String ip : occurrences.keySet()) {
values.add(ip);
if (values.size() > maxItems) {
values.poll();
}
}
for (int idx = 0; idx < maxItems; idx++) {
String ipAddress = values.poll();
context.write(ipAddress,occurrences.get(ipAddress));
}
}
}
这将为每个“地图”步骤收到的数据创建前10个最常用名称的列表。我不了解的一件事是,在最坏的情况下,您可能会得到一个名称列表,并且只出现1个,因为在此步骤中,所有名称偶然都只出现1次。
减少
我陷于“减少”步骤。我的解释是,Reduce步骤将收到一个键,值对的列表,其名称为-10、20、30(基本上是该名称出现的不同映射步骤的输出)。因此,简单地说,在Reduce步骤中,我们唯一需要做的就是遍历这些对,然后为该特定键创建所有对的和。
public static class Reduce extends Reducer<> {
protected void reduce(...) {
int sum = 0
for (IntWritable val : values) {
sum += val.get();
}
context.write(key,new IntWritable(sum));
}
}
(某些方法)
我的推理正确吗?为什么我发布的两个示例完全不同。如果要遵循这些示例,我会说我在Map步骤中构建了PriorityQueue,在Cleanup阶段中,我返回了该Map步骤的前K个。
但是我不了解Reduce步骤看起来是什么样子,除了它做的完全一样,只是重复代码而已。
对吗?但是,在此示例中,如何跨Reduce步骤汇总数据?还是每个Reduce步骤都接收多个键值对?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。