MapReduce的核心技术是排序,用来组织数据
准备
将一个MR作业设置成只有map函数,并通过job.setNumReduceTasks(0)不执行默认的reduce,所以输出不会按键排序
部分排序
> 使用默认的MR设置,最终结果产生按键排序
> 如果输出文件有多个,那多个分别按键排序,且文件串联非有序,则不是全体有序,可以使用MapFile发现键的所属分区,在分区查找记录
全排序
> 大文件实现全排序,如果只用一个Partitioner则无法体现并行的优势
> 创建排序文件,且分区使这些文件串联有序,串联后得到全局有序,这里关键是如何分区
根据数据分布均匀划分记录,遍历整个DataSet效率并不高,需要采样,采样的核心思想是只查看一小部分键,获得键的近似分布,由此构成分区
Hadoop内置了采样器InputSampler类实现接口Sampler
> Sampler接口 getSampler(InputFormat, Job),一般不由客户端调用,由静态方法InputSampler.writePartitionerFile()
创建一个顺序文件存储定义分区的键,可以指定采样率
> TotalOrderPartitioner使用顺序文件为排序作业创建分区
public interface Sampler<K, V>{
k[] getSample(InputFormat<K, V> inf, Job job) throws IOException, InterruptedException;
}
public static <K, V> void writePartitionFile(Job job, Sample<K, V> sampler) throws IOException, ClassNotFoundException, InterruptedException
> SplitSampler 只采样分片中的前n条记录
> IntervalSampler 一定的间隔定期从分片中选择键
> RandomSampler 优秀的通用采样器
> 自定义采样器
辅助排序 二次排序
1 思想
> 自然键和自然值组成新的键,叫组合键
> 分区和分组时只考虑键
> 对组合键中的键值排序,先对键排序,再对值排序
2 setPartitionerClass + setSortComparatorClass + setGroupingComparatorClass