个人理解

(嘿嘿嘿,不考虑阅读效果了)

shuffle分为map端shuffle和reduce端shuffle。
map端并不是处理一点写一点,而是先将处理的数据写入到环形缓冲区,缓冲区默认大小为100M,阈值默认为0.8,也就是说当阈值达到0.8即80M时,开始将数据以轮询方式写入到本地spll磁盘。如果缓冲区写入数据达到100M时,则将map暂时阻塞,等待缓冲区写出。在缓冲区写到磁盘前,先将其数据按照reduer来分区,并且对分区的数据进行一次内排序,仅对分区内排序。如果有combiner,则将相同key的进行合并,减小写入磁盘数据的大小,和磁盘的IO消耗。由于每次缓冲区spill溢写都会生成一个spill文件,map端的最后还要对这些spill进行合并,合并为一个已知分区已排序的文件,从map端到reduce端可以采用一种压缩速率较快的压缩方式,进行压缩,这样会提高速度以此map端结束
reduce端 reduce端第一个操作就是复制操作,少量复制线程并行的将存在于磁盘的文件复制到reduce的jvm内存或者磁盘中。如果map输出数据不多,则直接复制到jvm内存中,如果很大,则可以写到磁盘中。reduce通过心跳机制知道在map端的输出数据在哪里。这个操作并不是在所有map结束才开始进行,而是由一个参数掌控,reduce端内存缓冲区达到阈值或者达到map输出阈值,则合并溢写到磁盘中,当文件数的增多,后台线程自动的对文件先进行一次合并合并为更大的以排序的文件。当然如果设置了压缩,会在内存中解压缩,然后再合并。复制阶段到此结束。下一步时合并阶段,根据合并因子,将文件合并,例如合并因子为10,文件数为50,则结果为5个文件,但真实并不是每次十个那样子有规律的合并,而是相对以一种优化的方式,尽量减少写入到磁盘的数据量。最后一次合并是直接写到reduce阶段。reduce阶段就是函数对数据的处理,最后直接写到HDFS中或者输出。