Map 阶段负责数据的过滤分发,将原始数据转化为键值对;Reduce阶段是对数据进行合并,将具有相同的 key 值的 value 进行处理后再输出新的键值对作为最终结果。 为了让 Reduce 可以并行处理 Map 的结果,必须对 Map 的输出进行一定的分区排序,然后再交给对应的 Reduce。
(1)即 Map 方法之后 Reduce 方法之前的这段数据混洗的过程叫做 Shuffle机制 。
(2)Map
方法之后,数据首先进入到分区方法,把数据标记好分区,然后把数据发送到
环形缓冲区;环形缓冲区默认大小
100m
,环形缓冲区达到
80%
时,进行溢写;溢写前对数
据进行排序,对
key
的索引按字典顺序进行快速排序;溢写产生大量溢写文件,需要对溢写文件进行归并排序;最后将文件按照分区存储到磁盘,等待
Reduce
端拉取。
(对溢写的文件也可以进行
Combiner
操作,前提是
汇总操作,求平均值不行。)
(3)每个
Reduce
拉取
Map
端对应分区的数据。拉取数据后先存储到内存中,内存不够
了,再存储到磁盘。拉取完所有数据后,采用归并排序将内存和磁盘中的数据都进行排序。
在进入
Reduce
方法前,可以对数据按照相同的key进行分组操作。
相关问题:
1.为什么shuffle?
Shuffle是MR中非常重要的一个环节,它可以对map阶段输出的数据进行预处理,确保reduce阶段可以获取到所有相关的数据 。
shuffle操作的作用主要有以下三点:
- 将map阶段输出的数据按照key进行分组,确保reduce可以获取对应key的value。
- 在shuffle过程中对数据进行排序,以便后去reduce阶段可以更高效地处理数据。
- 将相同key的数据进行合并,降低后续reduce处理的数据量,提高程序的执行效率。
2.为什么使用环形缓冲区?
在shuffle过程中,环形缓冲区起到非常重要的作用。首先,MapTask会将输出结果先写入环形缓冲区中,待环形缓冲区中的数据达到阈值后开始向磁盘中写入,并且继续往环形缓冲区中写入数据,直到MapTask的运行结束。此时ReduceTask启动,从磁盘中读取MapTask所写的数据并放入内存池中,再使用归并排序进行处理。
因此,环形缓冲区的作用如下:
- 缓冲池: 扮演着一个缓冲池的角色,有效平衡Map和Reduce结点之间的速度差异和负载流量。
- 提高数据读写的效率: 环形缓冲区不需要频繁的内存分配和释放操作,只需要利用指针来移动读写位置。
- 降低存储空间的使用量: 环形缓冲区可以通过循环复用的方式,充分地利用已经写入的空间,避免浪费存储空间。
- 支持并发读写操作: 由于环形缓冲区是一个循环结构,读写指针可以同时移动,所以可以支持多个进程或者线程同时对其进行读写操作,提高并发性。
3.环形缓冲区的读写,内存是否可以复用?
可以复用!环形缓冲区对内存进行了循环复用,它不需要频繁地进行内存分配和释放操作,而是通过读写指针来移动位置,复用已经写入的空间,以此来提高读写效率并降低存储空间的使用量。因此,环形缓冲区的设计可以充分利用内存空间,减少内碎片,实现内存的复用。
4. MapReduce Shuffle中Reduce是怎么获得Map输出的分区文件,Map主动推还是Reduce主动拉?
答:Reduce主动拉取
5.shuffle中涉及到哪些排序?快排和归并排序时间复杂度是多少?
答:shuffle中涉及到快速排序和归并排序,快速排序和归并排序的时间复杂度都为O(nlogn
)