MapReduce中的shuffle过程

1.Map task输出k-v对

2.环形缓冲区

  map阶段在最后会通过MapOutputBuffer来将数据暂时存储到一个环形缓冲区,在缓冲区写入的数据达到阈值(80%)后,才会开始从这里再写出到磁盘(落盘)。由此可见:环形缓冲区的设计直接影响Map Task的输出效率。

  上面大致的流程中,我们不禁有这么几个疑问:

    1.什么是环形缓冲区?为什么使用它?

    2.缓冲区框架阈值为什么设置为80%?

    3.环形缓冲区内部的读写时是什么样的?

下面就通过整体上模拟来解决这些问题。

  2.1首先来认识下缓冲区:

  缓冲区包含有:单向、双向、环形。这里主要介绍环形。

  2.1.1 单向缓冲区:

  这个很简单,输出的数据直接向缓冲区单向的写入,写满后,一次性开始落盘。不断循环往复。也可以看出,它最大的缺点就是性能太低,不能并发状态下读写数据。

  2.1.2 双向缓冲区:

  针对于上面的单向缓冲区,在一定程度上进行了一些改进:使用两个缓冲区,原则上一读一写,交替进行,在一定程度上让读写并行(读写效率并不一致,所以有时还是做不到完全并发,出现读写等待的问题)。

 

 

 

  2.1.3 环形缓冲区:

  1— 》什么是环形缓冲区?

  上面双向缓冲区的基础上,再次改进,设计一个环形的(闭环)缓冲区,写入到一定阈值之后,开始写出,同时并发状态下,继续向不断增加的剩余空间写入,写入后写出某种意义上来讲,互不影响。完全达到并发读写

  

 

 

   2— 》工作原理:

  在环形缓冲区内保存好数据后(80%),有SpillThread线程来将数据写到一个临时文件中,当所有数据全部处理完成之后,对所有文件进行一次合并,生成一个终极文件。这样就使得Map Task任务中的的Collect阶段Spill阶段并行进行。

  3—》索引(写出时怎么找数据)

  环形缓冲区内部采用了两级索引,设计了三个环形内存缓冲区:kvoffsetskvindiceskvbuffer。框架默认这三个共占据空间大小为100M(可改)。其中:

    kvbuffer:真正的数据缓存区。存放的就是map端甩来的kv对,默认最多占据95%,超过这个值,便会触发SpillThread,开始溢写。

    kvindices:位置索引数组。存放的是kv值在数据缓冲中的起始位置。

    kvoffsets:kv偏移量索引数组。保存我们的key/value信息在位置索引kvindices中的偏移量。

  kvbuffer占95%,kvoffsets占3.75%,kvindices1.25%

 

  2.2 环形缓冲区工作原理

 

 

 

 

   将一个环形缓冲区展开来看成矩形,首尾本来是相接的最初,在开始位置有三个指针,(如图红、绿、蓝)分别用来标记写入过程中的开始写的位置(start),数据所占据的(末尾)位置index,以及标记要溢写部分的结尾位置(end)。

 

  2.3 环形缓冲区内工作流程

==============

  开始写入数据,index指针随着数据的写入向后移动,start和end保持不动。直到index标记到环形缓冲区80%的地方,此时end指针直接跳到index的位置,start指针不动。那么,此时从start位置到end位置这一区域内的数据,就是我们第一次要溢写的数据,开始溢写。

==============

  溢写的同时,start向后移动,同时,继续向环形缓冲区内写入,index指针向后移动,end指针保持不动,这样就使得读写并行。当上一次的溢写完成后,end指针此时如果跳转到了下一个80%的index位置,再次开始溢写。

==============

  80%=(end-start)+(index-end)

==============

  问:什么阈值设为80%?

job.getFloat(JobContext.MAP_SORT_SPILL_PERCENT, (float)0.8);

  这里解释一下,map完事之后,会放到一个内存缓冲区里面,上边那个0.8的阈值,说的就是只要使用到百分之80了,就可以做溢写,写到磁盘去。
  这里要百分之80的阈值做溢写的原因是:如果没有这百分之80做溢写这个事情
整个环形容器都做缓冲区,map一直输出把缓冲区给占满,没有空闲了,这个时候map会阻塞,就不能往后写了。会把空间给锁住,锁完之后开始做溢写,写完磁盘把空间腾出来之后,才可以继续往里写,这是个线性的时间。
  如果我们做了这百分之80的阈值,map输出向这百分之80写,写满了,还有百分之20, 这个时候,map向剩下的百分之20去写的同时,这百分之80做溢写,这个会有一部分时间轴重叠了,会压缩我们的时间,这就是为什么要80做阈值。当然我们可以根据数据来做调整。

 

posted on 2021-10-19 23:02  理想三旬_z  阅读(328)  评论(0编辑  收藏  举报

导航