一.概述
关于二次排序的文章,网上很多,比喻http://www.cnblogs.com/xuxm2007/archive/2011/09/03/2165805.html就写的不错。在此文基础上补充几点。
二.job.setPartitionerClass在什么地方被用到
mapper里每一次write,都会调用到
- collector.collect(key, value,partitioner.getPartition(key, value, partitions));注partitions = jobContext.getNumReduceTasks();
从而使用到PartitionerClass。
参考MapTask write方法 line690。
三.job.setSortComparatorClass
在sortAndSpill时触发。
而进入sortAndSpill的时机有map阶段正在进行时缓冲区的数据已经达到阈值,或者map阶段完后的output.close(mapperContext);顺便说一下Mapper的clean方法是在map阶段完成,我以前一直以为是map阶段完后执行。这也是为什么每一个Mapper的输出都是有序的原因,也是Reduce Shuffle阶段的准备。
原始文件
- 1 1b
- 1 1a
- 3 3a
- 2 2A
- 2 2a
采用快速排序(调用SortComparatorClass的compare方法)。生成的file.out文件。好像有些字符没显示出来。
11a1a11b1b22A2A22a2a33a3a?SU
代码MapTask line763
- try {
- input.initialize(split, mapperContext);
- mapper.run(mapperContext);//mapper阶段
- mapPhase.complete();
- setPhase(TaskStatus.Phase.SORT);
- statusUpdate(umbilical);
- input.close();//关闭RecordWriter
- input = null;
- output.close(mapperContext);
- output = null;
- } finally {
- closeQuietly(input);
- closeQuietly(output, mapperContext);
- }
四.job.setGroupingComparatorClass
决定了一个分区下的那些value,被分为一组。先阅读http://zy19982004.iteye.com/admin/blogs/2037907。在Merge & Sort阶段后,数据已经是有序的了。此时只需要比较当前value与下一个value是否相等(调用GroupingComparatorClass的compare方法),相等就为一组。 所以compare方法的返回值int没多大意思,因为只需nextValueIsSame = result == 0。上述数据的调用轨迹为
- TextPair [first=1, second=1a] TextPair [first=1, second=1b]
- TextPair [first=1, second=1b] TextPair [first=2, second=2A]
- TextPair [first=2, second=2A] TextPair [first=2, second=2a]
- TextPair [first=2, second=2a] TextPair [first=3, second=3a]