shuffle
Spill过程
Spill过程包括输出、排序、溢写、合并等步骤,如图所示:
Map任务会不断地以键值对的形式把数据输出到一个环形数据缓冲结构中,使用环形数据结构是为了更有效地使用内存空间,在内存中放置尽可能多的数据。超过自身80%的时候就会溢写到磁盘中。
详细流程
1、 mapTask 收集我们的 map()方法输出的 kv 对,放到内存缓冲区 kvbuffer(环形缓冲区:内存中的一种首尾相连的数据结构,kvbuffer 包含数据区和索引区)中
2、 从内存缓冲区中的数据区的数据不断溢出本地磁盘文件 file.out,可能会溢出多次,则会
有多个文件,相应的内存缓冲区中的索引区数据溢出为磁盘索引文件 file.out.index
3、 多个溢出文件会被合并成大的溢出文件
4、 在溢出过程中,及合并的过程中,都要调用 partitoner 进行分区和针对 key 进行排序
5、 在数据量大的时候,可以对 mapTask 结果启用压缩,将 mapreduce.map.output.compress 设为 true,并使用 mapreduce.map.output.compress.codec 设置使用的压缩算法,可以提高数据传输到 reducer 端的效率
6、 reduceTask 根据自己的分区号,去各个 mapTask 机器上取相应的结果分区数据
7、 reduceTask 会取到同一个分区的来自不同 mapTask 的结果文件,reduceTask 会将这些文件再进行合并(归并排序)
8、 合并成大文件后,shuffle 的过程也就结束了,后面进入 reduceTask 的逻辑运算过程(从文件中取出一个一个的键值对 group,调用用户自定义的 reduce()方法)
Shuffle 中的缓冲区大小会影响到 mapreduce 程序的执行效率,原则上说,缓冲区越大,磁盘 io 的次数越少,执行速度就越快
缓冲区的大小可以通过参数调整,参数:mapreduce.task.io.sort.mb 默认 100M 缓冲区的溢写比也可以通过参数调整,参数:mapreduce.map.sort.spill.percent 默认 0.8
问题(看图思考)
1.Merge的作用是什么?
2.reduce中merge过程有几种方式,与map有什么相似之处?
3.当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。排序是MapReduce模型默认的行为,这里的排序也是对谁的排序?
4.map task与reduce task的执行是否在不同的节点上?