MR之shuffle机制
一、shuffle阶段划分
Map方法之后,Reduce方法之前的处理过程就是shuffle阶段.(sort-copy-sort)
二、shuffle阶段流程分析
2.1 map方法写出数据
2.1.1 环形缓冲区
在内存中存有一个环形缓冲区,该缓冲区默认大小是100M,map()方法中写出的kv键值对数据会进入到环形缓冲区内,但是map()写出的kv数据是很大的,环形缓冲区不可能存的下,考虑到这一情况,设计者设置环形缓冲区的运行机制设置为:当写入环形缓冲区的数据达到整个缓冲区的80%时,发生溢写操作(落盘),将缓冲区内80%的kv数据溢写到磁盘,保证后续的数据可以陆续写入
2.1.2 为什么不等到将缓冲区写满再发生溢写操作
为了保证MR程序的正常运行,设计者预留出20%的空间,当缓冲区内80%的数据在执行溢写操作时,另外20%的空间仍然可以进行kv数据的写入操作(写入到缓冲区),从而不用终止map()方法写入的操作
2.1.3 map方法写出到环形缓冲区中的数据类型
map()方法写入缓冲区的数据不仅仅是键值对数据,同时还含有kv键值对数据的索引信息包括元数据meta信息、kv所属分区(在map方法写出数据进入到缓冲区前就计算出分区号)
2.2 排序操作
- 缓冲区内记录的N多个kv数据写入磁盘时,并不是直接进行一次性写入的,而是要对多个kv进行排序(按照key排序),默认情况下是按照字典序排序,将排好序的kv数据写出到不同的分区内,比如分区1、分区2…
- 注意:各分区内部的数据是独立进行排序的,互不影响 –map阶段第1次排序(快排)
- 注意:本次排序只是对索引进行排序,并不产生位置的交换,根据索引去内存中查找数据,溢写数据时直接根据索引找值
2.3 溢写操作
- 溢写操作~排好序的分区数据会溢写到一个文件中,该文件中存储多个分区的数据
- 那么整个map()方法写出的数据经过缓冲区处理后,可能是产生N多个溢写文件
- 对于reduce来讲,缓冲区的N多个溢写文件就是它要处理的数据
- 考虑到reduce合操作较弱的情况,因此设计者设计在每个map()方法经过缓冲区处理后产生的N多个溢写文件提前进行一次合并(归并操作),从而减缓reduce端合数据计算的压力.
- 注意:N多个溢写文件在进行归并排序时,各分区的数据在合并时仍然是做排序的 –map阶段第2次排序(归并排序)
- 局部有序的数据在做整体排序时,归并排序效率是很高的
2.4 reduce读取溢写文件
- –思考:reduce是直接从多个MapTask~map()方法 写出的多个溢写文件中 拷贝对应分区的数据做处理?
- 不是,原因:在一个MR程序中,MapTask的个数一般是大于ReduceTask个数的,因为分数据可以多台机器做,但是合数据reduce一定是少的,代表计算能力比较弱
- N多个MapTask任务执行完毕后,N多个map()方法,都会最终产生归并排序后的总溢写文件,那么ReduceTask在获取多个总溢写文件时,根据分区拷贝多个总溢写文件上对应的分区数据交给对应的reduce程序处理
- 当内存不够时会将数据写到磁盘,等全部数据读取完毕后,reduce对属于同分区的kv数据再次做归并排序,最后分组。
- 分组原因:相同key的多个kv组进入到同一个reduce方法做运算 –reduce端排序(归并排序)
( 每个ReduceTask按照所要处理的分区, 到每个MapTask中拷贝对应的分区的数据.)- reduce端对排好序的数据进行分组,然后进入reduce方法进行业务处理
三、相关基础知识:
MapReduce工作流程: https://blog.csdn.net/weixin_42796403/article/details/109817309
MR切片机制总结: https://blog.csdn.net/weixin_42796403/article/details/109811966
MR核心编程思想总结: https://blog.csdn.net/weixin_42796403/article/details/109802287
(https://blog.csdn.net/weixin_42796403/article/details/109806713)
TextInputFormat切片机制: https://blog.csdn.net/weixin_42796403/article/details/109811157