如果使用 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 字符串中确定任务是映射器还是减速器,但组合器和减速器似乎都具有相似的字符串模式。