编写Hadoop MapReduce作业时,排序操作执行位置的技术问询
MapReduce作业中的排序环节详解
嘿,这个问题我当初刚上手MapReduce的时候也纠结过,其实排序在MapReduce的好几个关键环节都在执行,我给你掰扯清楚:
1. Map端的本地溢写排序
当Map任务处理完数据输出键值对后,这些数据会先写入内存中的环形缓冲区(默认大小100MB)。当缓冲区使用率达到阈值(默认80%)时,就会触发**溢写(spill)**操作——在把数据写入磁盘前,MapTask会先对缓冲区里的所有键值对按Key进行排序,这就是本地排序,默认是按Key的自然升序排列。
如果你配置了Combiner(局部聚合函数),排序之后还会对相同Key的键值对做合并,但排序是溢写前的必经步骤。
2. Map端的合并排序
当Map任务完成所有数据处理后,磁盘上会生成多个溢写文件。这时候MapTask会把这些分散的溢写文件合并成一个完整的输出文件,合并过程中会再次对所有键值对按Key排序,最终输出的Map结果文件是全局有序的(针对该MapTask处理的数据范围)。
3. Reduce端的Shuffle排序
这是最容易被关注到的排序环节:
- ReduceTask会从各个Map节点拉取属于自己处理的键值对分片(也就是Shuffle阶段的拉取过程);
- 拉取到的数据会先缓存到本地内存或磁盘,当拉取完成后,ReduceTask会把这些来自不同Map的文件合并成一个大文件,合并时同样会按Key进行排序;
- 排序完成后,相同Key的键值对会被分组,然后才会把分组后的键值对交给Reduce函数处理。
实用开发提示
如果你的业务需要自定义排序规则(比如按Key降序、或者按自定义对象的某个属性排序),只需要让你的Key类实现WritableComparable接口,重写compareTo()方法即可。举个简单的逆序排序例子:
public class ReverseIntKey extends IntWritable { @Override public int compareTo(IntWritable other) { // 反转默认的升序逻辑,实现降序 return -super.compareTo(other); } }
内容的提问来源于stack exchange,提问作者Harshali Patel
相关产品推荐
相关产品推荐

