Hadoop-MapReduce Shuffle原理及调优
Shuffle过程图:
Map端:
1.Collect:
Map端不是直接把数据写入本地磁盘,而是先写入一个环形缓冲区,
每个Map任务都有一个区,由io.sort.mb属性控制缓冲区大小。
2.sort:
将数据按照分区分好,并且在分区内实现按Key升序排序
2*.Combiner:
若有Combiner,在上面分区内sort的输出结果基础上再执行Combiner,
相当于一次局部Reduce,精简数据,减少IO传输和网络传输的负担。
3.spill(溢写)
3.1.当缓冲区的数量达到一定值(由io.sort.spill.percent属性控制,默认为0.8),
会启动一个后台线程将缓冲区中的数据溢写到本地磁盘。
3.2.在该过程中,Map任务继续将数据送到缓冲区;
若缓冲区已满,就会阻塞Map任务。
3.3.线程写入按分区依次写入文件。分区在文件里也称作segmen(段)。
3.4.spill文件位置由mapred.local.dir指定。
3.5.输出到磁盘前可对数据先进行压缩,由mapred.compress.map.output属性控制
默认为false。
4.Merge:
Map输出的数据量很大,溢写出来的文件很多,就是用Merge来合并文件。
例如:一个文件中的(“aaa”,5)和另一个文件中的(“aaa”,7),更多的相同Key,
会合并为(“aaa”,[5,7,···])。
Reduce端:
1.copy:
1.1.Reduce任务拥有多个线程去拉取拷贝Map的输出,
线程数由mapred.reduce.parallel.copies控制,默认为5.
1.2.由于很多Map任务,不是同时完成的,因此当完成了的Map数占中的Map数一定比例,
Reduce任务就开始拉数据。
由mapred.reduce.slowstart.completed.maps控制,默认为0.05(即20%完成)
1.3.每个节点都有HTTP Server,当有Map output请求,HTTP Server就读取
Map到这个Reduce对应的文件通过网络发送给Reduce任务。
2.sort (包括 Merge):
2.1.由于Map传输过来的数据是局部有序的,所以在调用sort实现实现一个
Reduce任务里的有序。
2.2.通过不断归并Map输出,归并排序(Merge and Sort)。
2.3.若有50个Map输出,归并因子为10,即一次将归并10个文件归并成一个文件,
归并成5个文件,需5次Merge。
归并因子由io.sort.factor控制。
Shuffle调优:
Map端:
1) io.sort.mb
用于map输出排序的内存缓冲区大小
类型:Int
默认:100mb
备注:如果能估算map输出大小,就可以合理设置该值来尽可能
减少溢出写的次数,这对调优很有帮助。
2)io.sort.spill.percent
map输出排序时的spill阀值(即使用比例达到该值时,将缓冲区中的内容spill 到磁盘)
类型:float
默认:0.80
3)io.sort.factor
归并因子(归并时的最多合并的流数),map、reduce阶段都要用到
类型:Int
默认:10
备注:将此值增加到100是很常见的。
4)mapred.compress.map.output
map输出是否压缩
类型:Boolean
默认:false
备注:如果map输出的数据量非常大,那么在写入磁盘时压缩数据往往是个很好的主意,
因为这样会让写磁盘的速度更快,节约磁盘空间,并且减少传给reducer的数据量。
5)mapred.map.output.compression.codec
用于map输出的压缩编解码器
类型:Classname
默认:org.apache.hadoop.io.compress.DefaultCodec
备注:推荐使用LZO压缩。Intel内部测试表明,相比未压缩,
使用LZO压缩的 TeraSort作业,运行时间减少60%,且明显快于Zlib压缩。
6) tasktracker.http.threads
每个tasktracker的工作线程数,用于将map输出到reducer。
(注:这是集群范围的设置,不能由单个作业设置)
类型:Int
默认:40
备注:tasktracker开http服务的线程数。用于reduce拉取map输出数据,
大集群可以将其设为40~50。
Reduce端:
1)mapred.reduce.slowstart.completed.maps
调用reduce之前,map必须完成的最少比例
类型:float
默认:0.05
2)mapred.reduce.parallel.copies
reducer在copy阶段同时从mapper上拉取的文件数
类型:int
默认:5
参考:https://blog.****.net/shudaqi2010/article/details/80266834