shuffle & sort解释

转载请标明出处:http://blackwing.iteye.com/blog/1848401

MR任务,充分利用了缓存进行读写。

1)map端
每个map任务,都会先把数据写到一个环形缓存中,该缓存默认大小是100MB,由io.sort.mb(默认值是100MB)和io.sort.spill.percent(默认值是0.8)共同决定。在默认情况下,当缓存达到80MB时,后台线程就开始把数据spill到磁盘。而map会继续写数据到缓存中,当100MB的缓存写满后,map就会阻塞,直到spill完成。

在spill写数据到磁盘前,线程会根据reducer的数量(例如10个reducer)把输出数据切分为相应个数的partition,在每个partition中,后台线程会对其中的数据进行排序,如果该job有combiner,则此时也会调用combiner对数据进行合并。partition是逻辑划分,是指一个spill的文件中,或逻辑划分为几个partition。

在map结束前,如果有超过min.num.spills.for.combine(默认值3)个spill,则这些spill会被合并成一个分好区的大文件。

每个map生成的数据,会通过http传输给reducer。

2)reduce端
reducer通过http把map输出的数据copy到本地,copy数据的线程数由mapred.reduce.parallel.copies进行设置(默认值5)。

如果map的输出数据足够小,则会直接写入缓存中(由mapred.job.shuffle.input.buffer.percent设置,指占JVM的比例),否则写入磁盘。当缓存数据达到mapred.job.shuffle.merge.percent(默认0.8)或者超过mapred.inmem.merge.threshold(默认1000)个文件,则开始把数据spill到磁盘。此时如果job有combiner,则会调用它以减少写入磁盘的数据。

在数据不断写入磁盘同时,后台线程会把这些数据合并成一个更大的排好序的文件,节省后续合并的时间。当所有map的输出都copy到reducer后,就进入合并排序阶段,生成一个有序的大文件。

总结来说,调用combiner的地方如下:
*map端spill数据到磁盘
*map端,map结束前,合并多个spill
*reduce端spill数据到磁盘

《hadoop in practice》作者的spill过程图解:
http://grepalex.com/2012/09/24/map-partition-sort-spill/

猜你喜欢

转载自blackwing.iteye.com/blog/1848401