【发布时间】:2012-08-13 04:47:14
【问题描述】:
如果使用 MapReduce 执行的操作不是可交换的和关联的,那么 combiner 不能和 reducer 相同。
例如,在计算平均值时,组合器将键的值求和,然后归约器求和,然后将总和除以该键的值的总数。组合器的代码只有轻微的修改。如果您可以对 combiner 和 reducer 使用相同的类,并且可以确定当前任务是 combiner 还是 reducer,那会怎样?如果它发现它是一个reducer,那么它将总和除以计数。
类似这样的:
protected void reduce(Text keyIn, Iterable<PairWritable> valuesIn,
Context context)
throws IOException, InterruptedException {
double sum = 0.0d;
long count = 0l;
for (PairWritable valueIn : valuesIn) {
sum += valueIn.getSum();
count += valueIn.getCount();
}
if (THIS_IS_A_REDUCER) {
sum /= count;
}
context.write(keyIn, new PairWritable(sum, count));
}
可以这样做吗?上面的代码THIS_IS_A_REDUCER的和平可以换成什么吗?
我可以从任务尝试 ID 字符串中确定任务是映射器还是减速器,但组合器和减速器似乎具有相似的字符串模式。
【问题讨论】:
-
定义两个类这么糟糕?你可以从你的组合器中扩展并实现一个额外的抽象方法。例如
double finishOperation(double sum, long count) // returns the new sum -
扩展合并器是个好主意。你说“定义两个类这么糟糕?”。你是在问还是断言它不好?
-
问题是您是否对合并器的子类化有信心;)
标签: hadoop mapreduce combiners