MapReduce的shuffle

一、概述

        MapReduce会确保每个 reducer 的输⼊都是按键排序的。从 map ⽅法输出数据开始、到作为输⼊数据传给reduce ⽅法的过程称为 shuffle 。在此,我们将学习 shuffle是如何⼯作的,因为它有助于我们理解⼯作机制(如果需要优化MapReduce 程序)。shuffle 属于不断被优化和改进的代码库的⼀部分,因此会随着版本的不同,细节上可能会发⽣变量。不管怎样,从许多⽅⾯来看,shuffle MapReduce ⼼脏 “,是奇迹发⽣的地⽅。

二、环形缓冲区

        每个map 任务都会有⼀个环形内存缓冲区⽤于存储 map 的输出数据。在默认情况下,缓冲区的⼤⼩为100MB, 这个值可以通过 mapreduce.task.io.sort.mb 属性来调整。⼀旦缓冲区的内容达到阙值(默认是0.8 ,或者是 80% ,属性是mapreduce.map.sort.spill.percent),⼀个后台线程便开始把内容溢写 (spill) 到磁盘⾥,这个位置由属性mapreduce.cluster.local.dir 来指定的。在将数据溢写到磁盘过程中,map 的输出数据继续写到缓冲区,但如果在此期间缓冲区被填满, map 会被阻塞直到写磁盘过程完成。
         环形缓冲区:其实是⼀个字节数组kvbuffer. 有⼀个 sequator 标记, kv 原始数据从左向右填充( 顺时针 )
        kvmeta是对 kvbuffer 的⼀个封装,封装成了 int 数组,⽤于存储 kv 原始数据的对
应的元数据 valstart ,keystart, partition vallen 信息,从右向左 ( 逆时针 )。

 

 

 三、shuffle整体流程图

shuffle阶段是处于map阶段到reduce阶段的一个过程

        a) 完整地从 map task 端拉取数据到 reduce 端。
        b) 在跨节点拉取数据时,尽可能地减少对带宽的不必要消耗。
        c) 减少磁盘 IO task 执⾏的影响。

四、shuffle流程

1. map 函数输出到 reduce 函数接受输⼊数据,这个过程称之为 shuffle.
2. map 函数的输出,存储环形缓冲区(默认⼤⼩ 100M, 阈值 80M
       
3. 当达到阈值时,准备溢写到本地磁盘 ( 因为是中间数据,因此没有必要存储在 HDFS上) 。在溢写前要进⾏对元数据分区 (partition) 整理,然后进⾏排序 (quick sort,通过元数据找到出key ,同⼀分区的所有 key 进⾏排序,排序完,元数据就已经有序了,在溢写时,按照元数据的顺序寻找原始数据进⾏溢写)
4. 如果有必要,可以在排序后,溢写前调⽤ combiner 函数进⾏运算,来达到减少数 据的⽬的
5. 溢写⽂件有可能产⽣多个,然后对这多个溢写⽂件进⾏再次合并 ( 也要进⾏分区和排序) 。当溢写个数 >=3 时,可以再次调⽤ combiner 函数来减少数据。如果溢写个数 <3时,默认不会调⽤combiner 函数。
6. 合并的最终溢写⽂件可以使⽤压缩技术来达到节省磁盘空间和减少向 reduce 阶段传输数据的⽬的。(存储在本地磁盘中)
7. Reduce 阶段通过 HTTP 写抓取属于⾃⼰的分区的所有 map 的输出数据 ( 默认线程数是5,因此可以并发抓取 )
8. 抓取到的数据存在内存中,如果数据量⼤,当达到本地内存的阈值时会进⾏溢写操作,在溢写前会进⾏合并和排序( 排序阶段 ) ,然后写到磁盘中,
9. 溢写⽂件可能会产⽣多个,因此在进⼊ reduce 之前会再次合并 ( 合并因⼦是 10), 最后⼀次合并要满⾜10 这个因⼦,同时输⼊给 reduce 函数,⽽不是产⽣合并⽂件。reduce函数输出数据会直接存储在 HDFS 上。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值