java - 如何在不缓存 hadoop 1.0.3 的情况下多次迭代 hadoop reduce 值?

标签 java hadoop iterator mapreduce amazon-emr

我有一个问题,我基本上想做这样的事情:

    public void reduce(Text key, Iterable<Text> iterValues, Context context){

           for (Text val : iterValues){
               //do something
           }

           iterValues.reset()
           for (Text val : iterValues){
               //do something else
           }
}

我知道最好避免这些情况,或者简单地在内存中实例化对象,但我遇到了一个问题,我可能有太多的东西要保存在内存中,并且在结构上会变得更加复杂以破坏这变成了更多的减少步骤。

看起来我不是唯一一个在寻找这个功能的人,事实上,这是一个很久以前实现的功能: https://issues.apache.org/jira/browse/HADOOP-5266

MarkableIterator 类似乎正是我要找的:http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/MarkableIterator.html

但是它似乎只在 hadoop 2.0.3-alpha 中可用。我希望在仅支持 1.0.3(我当前使用的)或 0.20.205 的 EMR 中运行它。我一直在尝试各种各样的事情,但我没有在 1.0.3 中找到任何给我类似功能的东西。我最接近的方法是使用 StreamBackedIterator,它仍在内存中累积对象,但似乎比 ArrayList 的内存效率更高。

有人知道在 Hadoop 1.0.3 中执行此操作的方法吗?

最佳答案

这有点 hack,但您可以让您的 Mapper 发出每个值两次,但在一次中设置了一些标志,而在另一个中不设置。然后首先根据该标志对值进行排序,然后根据您想要的任何自然顺序进行排序。然后,您必须执行一些自定义逻辑,以在您达到第二组值后停止第一个循环。

除此之外,不,我没有看到一个简单的方法来做到这一点,而不是简单地自己将它们存储在内存中。主要问题是迭代器实际上并不返回新对象,它返回相同的对象,但在对 next() 的调用之间发生变化。在幕后,Hadoop 甚至可能不会缓存整组值,因此重置迭代器将需要重新扫描文件(我猜他们在新版本中正在这样做)。

关于java - 如何在不缓存 hadoop 1.0.3 的情况下多次迭代 hadoop reduce 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15260391/

相关文章:

java - 如何查找并调试实际代码行 Java 错误 : Fatal Exception: java. lang.IndexOutOfBoundsException:

python - 从 Python 连接 Hive 远程服务器

hadoop - 如何保证 combiner 在 map/reduce 中至少运行一次?

c++ - 运行时错误 : RunTime Error : map/set iterators incompatible

java - 在 org.apache.hadoop.mapred.MapTask$NewOutputCollector 关闭期间忽略异常

java - 关于Web脚本 Controller 类、Spring、AMP和编译的问题

java - 如何终止 JSF 中 Java 方法或 Java 类的运行 (PrimeFaces 3.0)

database - 了解HIVE数据库中的映射器和化简器

c# - 迭代器和枚举器的区别

python - 如果未使用特定迭代器,类似 zip 的函数将失败