gpt4 book ai didi

hadoop - 在 mapreduce 中操作迭代器

转载 作者:可可西里 更新时间:2023-11-01 14:20:21 27 4
gpt4 key购买 nike

我正在尝试使用 hadoop 找到任何给定点的总和,我遇到的问题是从单个 reducer 中的给定键获取所有值。看起来像这样。

reducer :

 public static class Reduce extends MapReduceBase implements
Reducer<Text, IntWritable, Text, DoubleWritable> {

public void reduce(Text key, Iterator<IntWritable> values,
OutputCollector<Text, DoubleWritable> output, Reporter reporter)
throws IOException {
Text word = new Text();

Iterator<IntWritable> tr = values;
IntWritable v;
while (tr.hasNext()) {
v = tr.next();

Iterator<IntWritable> td = values;
while (td.hasNext()) {

IntWritable u = td.next();
double sum = u+v;
word.set( u + " + " + v);
output.collect(word, new DoubleWritable(sum));
}
}
}
}

我正在尝试创建 Iterator 变量的两个副本,以便我可以遍历第二个迭代器的所有值,同时从前一个迭代器获取单个值(上面的两个 while 循环)但是两个迭代器持有始终具有相同的值。

我不确定这样做是否正确。

最佳答案

reducer 中的迭代器并不像你想象的那么简单。

问题是您正在迭代的项目总数可能不适合内存。这意味着迭代器可能正在从磁盘读取。如果您有两个独立的迭代器副本,那么您可以让其中一个远远领先于另一个,这意味着不能删除两个迭代器指向的位置之间的数据。

为了简化实现,Hadoop 不支持为 reduce 值使用多个迭代器。

这样做的实际影响是您不能通过同一个迭代器两次。这不好,但事实就是如此。如果您绝对知道项目的数量将适合内存,那么您可以按照 MrGomez 的建议将所有项目复制到列表中。如果您不知道,您可能不得不使用辅助存储。

更好的方法是重新设计您的程序,这样您就不需要在 reducer 中无限存储。这可能有点棘手,但有解决该问题的标准方法。

对于您的特定问题,输出大小相对于最大归约输入集呈二次增长。这通常是一个非常糟糕的主意。在大多数情况下,您不需要所有对,只需要最重要的对。如果您可以通过某种方式修剪成对集合,那么您就万事大吉了,您也许可以移除所有成对约束。

例如,如果您试图为每个归约集找到具有最大总和的 100 对,您可以保留一个优先级队列,其中包含迄今为止看到的 100 个最大输入和一个具有迄今为止看到的 100 个最大总和的优先级队列.对于每个新输入,您可以用迄今为止看到的最大 100 个数字形成总和,并尝试将这些总和放入第二个队列。最后,您应该将新输入放入第一个队列,并通过删除最小值(如有必要)将两个队列修剪为 100 个元素。在 reduce 的关闭方法中,您应该转储优先级队列。这种方法保证您只需要 min(n^2, 200) 个存储元素,从而避免了 n^2 问题,并通过保留 100 个最大的项目而不是所有项目来避免重复输入。

关于hadoop - 在 mapreduce 中操作迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3481914/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com