跑其他的mr任务没有出现这种情况,一直以为是跑完map再跑reducer
这里会涉及到一个阈值的问题就是当map任务完成到多少的时候就会启动reduce任务,并不是map结束后才跑reduce
- 什么是Shuffle?
Hadoop的shuffle过程就是从map端输出到reduce端输入之间的过程,这一段应该是核hadoop中最心的部分,因为涉及到Hadoop中最珍贵的网络资源。
- Map阶段:这里以一个Map任务为例,inputSplit(切片)的数量代表Map任务的数量,当Map任务提交的数据会存在buffer in memory(内存中的溢写缓冲区或是环形内存缓冲区)(数据已经分好区和排序)中,默认溢写缓冲区的大小为100M,溢写阈值为80M,当溢写缓冲区中的数据达到80M,一个后台线程会将内容写入本地磁盘的Spill文件(分区和排序),Spill文件可能生成多个(不能单纯根据128M切片来决定Spill文件数量,由Mapper里面的代码决定)当一个任务完成时,即不再输出k,v时的时候,开始合并Merge文件结果文件(分区和排序)。
注意:map过程的输出是写入本地磁盘而不是HDFS,但是一开始数据并不是直接写入磁盘而是缓冲在内存中,好处在于减少磁盘IO的开销,提高合并和排序的速度。所以在在map中尽量减少内存的使用,为shuffle过程预留更多的内存,因为该过程是最耗时的。
- Reduce阶段:Reducer通过Http方式得到输出文件的分区。reduce端可能从n个map的结果中获取数据,而这些map的执行速度不尽相同,当其中一个map运行结束时,reduce就会从 JobTracker中获取该信息。map运行结束后TaskTracker会得到消息,进而将消息汇报给JobTracker,reduce定时从 JobTracker获取该信息,reduce端默认有5个数据复制线程从map端复制数据。然后将这些文件合并方为最终的Merge文件,合并的结果作为reduce的输入而不是写入到磁盘中。当Reducer的输入文件确定后,整个Shuffle操作才最终结束。之后就是Reducer的执行了,最后Reducer会把结果存到HDFS上。
2.Hadoop调优策略
a.调节溢写缓冲区大小,减少Spill溢写次数,减少磁盘I/O次数
b.加入Combiner中间过程,在溢写缓冲区就会发生Combiner,好处是:
比如——hello 1 hello 1一共占14个字节,Combiner 后,变为hello 2 。所以也能够间接减
少Spill溢写次数,从而提高性能。
c.加入Combiner中间过程,在Merger过程中,可能会发生Combiner,意义是能够减少最后
结果的大小,从而能够减少Reduce Fetch的数据量,节省带宽,提供性能。
注:为什么有可能不发生Combiner,如果最后的Spill文件数量是一个,则Spill文件相当于是
最后的结果文件——即没有Merge过程——也就没有Combiner过程。此外,当Spill文件是2
个时候,也不会发生Combiner。
综上:在Merger过程,如果Spill文件的数量小于3,则不会发生Combiner。
d.在Reduce 抓取分区数据时,是由线程来处理的,为了提高效率,我们的策略是让抓取线程
尽可能等于或接近于Map任务数量,从而达到并行抓取的效果。
e.适当调大Merge合并因子(Hadoop默认是10)
f.Reduce任务并不是等所有的Map任务都完成后才启动的,Hadoop有一个默认的启动阈
值,5%(0.05)。所以这个值可以适当减小。