【问题标题】:Pass small number of values from Mapper to Reducer将少量值从 Mapper 传递到 Reducer
【发布时间】:2012-06-16 05:42:26
【问题描述】:

如何将 Mapper 中收集的少量元数据传递给 Reducer?在我的具体问题中,我只想传递两个 long 值,因此我不会为这些值使用 MultipleOutputFormatMultipleOutputs

我尝试过的一些变体:

(1)

映射器

    context.getCounter("Countergroup", "Counter").increment(1);

减速器

    counter = context.getCounter("Countergroup", "Counter").getValue(); 

计数器不会定期更新,因此 Reducer 中的函数调用会产生 0 值。



(2)

映射器

    context.getConfiguration().setInt("Counter", countTotal);

减速器

    counter = context.getConfiguration().getInt("Counter", 0);          

在运行作业期间当然不能更改配置(值得一试)。

已经有关于这个问题的问题,但我找不到有效的答案。此外,API 也发生了变化。我正在使用 Hadoop 0.20.2。



类似的问题:

Passing values from Mapper to Reducer

Accessing a mapper's counter from a reducer (这看起来很有希望,但它似乎不适用于 0.20.2 API)

【问题讨论】:

    标签: java hadoop


    【解决方案1】:

    如果您无法使用计数器找到问题的解决方案(在特定情况下将两个长值从映射器传递到减速器),另一种方法可以利用 order inversion 模式。 p>

    在此模式中,您所做的是从 map 中发出一个额外的键值对,其中键是某种东西,它成为 reducer 接收的第一个键(利用 reducer 按排序顺序接收键的事实)。例如,如果您发出的键是从 1 到 1000 的数值。您的虚拟键可能是“0”。由于 reducer 按排序顺序接收键,因此保证在处理任何其他键之前处理伪键。

    您在新 API 中还具有 SetUp() 和 CloseUp() 方法(旧 API 中也有类似方法,但我不记得名称)以利用它们只执行一次的事实每个节点,在该节点上的所有 map/reduce 任务开始/完成之前/之后。

    【讨论】:

    • 只有当你只有一个减速器时才有效。我从 OP 的问题中了解到,这个元数据需要对所有 reducer 可用,而不仅仅是碰巧运气好并获得特殊密钥的那个。如果您可以避免数据膨胀,您可以将元数据多路复用到所有键,从而保证每次调用 reduce() 都能看到它,并且您可以做一些额外的辅助排序技巧以确保在迭代时首先看到元数据值组。
    • 是的,我同意它仅适用于 1 个减速器,除非数据足够大,以至于程序在使用 1 个减速器时变得太慢。否则,您可以发出多个键并编写自定义分区器。我同意发出多个键可能不是很干净,但它是与使用每个键值对发出元数据并进行二次排序的权衡,因为后一种方法会使您使用大量不必要的内存。
    • 现在那个我喜欢(自定义分区器)。发出与 reducer 一样多的键,并通过分区器确保每个 reducer 获得一份副本,并通过自定义比较器确保元数据键位于所有真实键之前。
    • 非常感谢;这个小技巧在我当前的解决方案中效果很好。对于额外的第一条记录,我需要找到肯定不会出现在数据集中的值(至少在这里可以用代码解决),然后会首先出现在我的排序结构中。
    • 通过在键中添加布尔值(例如 isMetadata)和适当的 compareTo() 函数,可以更轻松地实现附加的第一个元素。
    猜你喜欢
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2013-11-05
    • 1970-01-01
    相关资源
    最近更新 更多