按两个值分组的化简器

  • 本文关键字:两个 hadoop mapreduce
  • 更新时间 :
  • 英文 :


我有一个情况,其中映射器发出属于子组的数据,而子组属于一个组。

我需要将子组中的所有值相加,并为每个组找到组的所有子组之间的最小值。

所以,我有一个来自映射器的输出,看起来像这样

Group 1
group,subgroupId,value
Group1,1,2
Group1,1,3
Group1,1,4
Group1,2,1
Group1,2,2
Group1,3,1
Group1,3,2
Group1,3,5
Group 2
group,subgroupId,value
Group2,4,2
Group2,4,3
Group2,4,4
Group2,5,1
Group2,5,2
Group2,6,1
Group2,6,2

我的输出应该是

Group1, 1, (2+3+4)
Group1, 2, (1+2)
Group1, 3, (1+2+5)
Group1 min = min((2+3+4),(1+2),(1+2+5))

组 2 相同。

所以我实际上需要分组两次,首先按组分组,然后在内部按子组进行分组。

所以我应该从一个组中发出最小和,

在给定的示例中,我的化简器应该发出 (2,3),因为最小和是 3,它来自 id 为 2 的元素。

因此,似乎可以使用两次reduce最好地解决,首先reduce将获得按id分组的元素,然后将其传递给按组id分组的第二个Reducer。

这有意义吗以及如何实现它?我见过ChainedMapper和ChainedReducer,但它们不适合这个目的。

谢谢

如果所有数据都可以放入一台机器的内存中,则可以简单地使用单个化简器(job.setNumReducers(1);)和两个临时变量在单个作业中完成所有这些操作。输出在减速器的清理阶段发出。如果您使用新的Hadoop API(支持cleanup()方法),则这是伪代码:

int tempKey;
int tempMin;    
setup() {
    tempMin = Integer.MAX_VALUE;
}
reduce(key, values) {
    int sum = 0;
    while (values.hasNext()) {
        sum += values.next();
    }
    if (sum < tempMin) {
        tempMin = sum;
        tempKey = key;
    }
}
cleanup() { //only in the new API
    emit(tempKey, tempMin);
}

你的方法(总结如下)是我会怎么做的。

作业 1:

  1. 映射器:将id分配给subgroupid
  2. 合路器/减速器(同类):查找 的最小value subgroupid .

工作 2:

  1. 映射器:将groupid分配给subgroupid
  2. 合路器/化简器(同类):查找 的最小value groupid .

由于以下原因,最好在两个作业中实现:

  • 显著简化了映射器和化简器(您无需担心第一次找到所有groupids)。在映射器中查找(groupid, subgroupid)对可能并非易事。编写两个映射器应该是微不足道的。
  • 遵循Tom White在Hadoop:The Definitive Guide(第6章)中给出的mapreduce编程指南。
  • Oozie工作流程可以轻松简单地适应相关作业。
  • 中间文件产品(key:subgroupid, value: min value for subgroupid)应较小,从而限制网络资源的使用。

相关内容

  • 没有找到相关文章

最新更新