values, Context context)
throws IOException, InterruptedException {
......
}
通常Reduce Function的结果被直接写出至HDFS。
这里需要重点理解一下“同一个键”,上面的描述实际隐藏了一个被称为“Group”的阶段,这个阶段决定着哪些键值对属于同一个键。如果没有特殊设置,只有在Map Task输出时那些键完全一样的数据属于同一个键,但这是可以被改变的,如下所示:
(a,b,c : 1)
(a,b,c : 2)
(a,c,e : 3)
(b,c,d : 4)
......
如果没有特殊设置,(a,b,c : 1)、(a,b,c : 2)会一并Reduce Function,而(a,c,e : 3)、(b,c,d : 4)会分别进入Reduce Function。
如果我们的计算需求要求我们统计键的第一个字母相同的所有值的和,这时就要求我们将(a,b,c : 1)、(a,b,c : 2)、(a,c,e : 3)合并进入Reduce Function,而且它们的键值为a,b,c,即第一个键值对的键值。
Group阶段决定哪些键值对属于同一个键的计算过程实际也是由一个RawComparator完成的,由属性mapred.output.value.groupfn.class决定,其实就是在键值对不断输入的过程中检查下一个键是否与当前键一致,从而决定哪些键值对属于同一个键。
一般情况下,Combiner与Reducer实际上是同一个类,亦即Combiner也存在Group阶段,但是要注意,Combiner(可能发生于三个地方)与Reducer在Group阶段使用的RawComparator是不一样的,Combiner使用的RawComparator由mapred.output.key.comparator.class指定,而Reducer使用的RawComparator由mapred.output.value.groupfn.class指定。
结语
通常MapReduce被人们粗略地认为只有两个阶段,即Map阶段、Reduce阶段,通过上面的介绍我们可以了解到在Map与Reduce之间存在着很复杂的Shuffle操作,涉及到数据的partition、sort、[combine]、spill、[comress]、[merge]、copy、[combine]、merge、group,而这些操作不但决定着程序逻辑的正确性,也决定着MapReduce的运行效率。io.sort.spill.percent调整
原文:http://www.cnblogs.com/sagqawe/p/4179054.html