本文是学习时的自我总结,用于日后温习。如有错误还望谅解,不吝赐教。
此处附上一篇个人认为写的比较好的博客,转自枝叶飞扬的博文:http://blog.sina.com.cn/s/blog_605f5b4f010188lp.html###
将Map的输出作为Reduce的输入的过程就是Shuffle了,这个是MapReduce优化的重点地方
Shuffle 过程
① Map在内存中开启一个默认大小100MB的环形内存缓冲区用于输出
② 当缓冲区内存达到默认阈值 80% 时,Map 会启动守护进程,把内容写到磁盘上,这个过程叫做Spill。另外的20% 内存可继续写入数据,写入磁盘和写入内存互不干扰
③ 如果缓存区被撑满,Map 会阻塞写入内存的操作,在写入磁盘操作完成后再继续写入内存
④ 排序阶段是在写入磁盘的时候进行的,如果有Combiner,排序前会执行Combiner
⑤ 每次Spill写入磁盘操作会产生溢出文件,当Map输出全部完成后,Map会合并这些文件
此处的小文件合并,是对于不同分区进行小文件合并,即同一个Map输出的所有小文件应该根据分区进行文件合并
⑥ Reduce阶段中,一个Partition对应一个Reduce作业,Reduce会根据Partition找到对应的map输出文件,进行复制操作,复制过程中Reduce会进行排序操作和合并文件操作
Shuffle 优化
① 分区:默认哈希算法分区,满足不了业务需求时需要按业务要求重写
public int getPartition(K key, V value, int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; }
② 分组:默认相同的Key在一组,如果业务要求某些不同的Key按一组来调用一次reduce(),这时需要重写
③ 排序:默认按字典排序,如果业务上要求不是这样,比如要求降序或者按其它条件来排,需要重写