【问题标题】:How can I iterate through a hadoop reduce values iterable more than once without caching in hadoop 1.0.3?如何在不缓存 hadoop 1.0.3 的情况下多次迭代 hadoop reduce 值?
【发布时间】:2013-03-06 23:43:18
【问题描述】:

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

    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
           }
}

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

似乎不是我一个人在寻找这个功能,事实上,这是一个不久前实现的功能: 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 中执行此操作的方法?

【问题讨论】:

    标签: java hadoop iterator mapreduce amazon-emr


    【解决方案1】:

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

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

    【讨论】:

    • 我会用不同的键发出每个值两次 :) 它们甚至可以是分区到同一个 reducer 的键。
    猜你喜欢
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多