MapReduce环形缓冲区分析1以及知识点

一、环形缓冲区相关类和属性说明

1、MapTask  或者  MapOutputBuffer:

默认的环形缓冲区类,可以通过job配置文件的参数***mapreduce.job.map.output.collector.class***进行设置。

2、sorter:

默认的排序类,可以通过job配置文件参数**map.sort.class进行设置,此类必须是IndexedSorter类的子类。

3、kvbuffer(环形缓冲区):

是一个字节数组,用于保存mapoutput数据的meta信息(16B),key,value值,默认大小是100M,可以通过参数mapreduce.task.io.sort.mb设置环形缓冲区的大小(单位MB)。

4、kvmeta:

用于存储key、value值的元数据信息。

5、kvindex,bufindex:

分别对应下一个meta数据,和key、value数据将被存放的位置。

6、kvstart,kvend,bufstart,bufend,bufmark:

bufmark用于记录当前插入key的开始位置,记录插入完成后bufmark=bufindex;bufstart是kvbuffer存放key,value数据部分的开始位置,bufend通常等于bufstart,在溢写时等于bufindex的当前值,kvstart和kvend用于管理meta数据,类似bufstart和bufend。

7、bufferreMaining,softLimit:

作为判断是否发生溢写的条件,初始时bufferRemaining=soflimit=kvbuffer.length*溢写占比(默认0.8)。以后每插入一条记录,bufferRemaining  -  记录size。

二、环形缓冲区初始化

通过调用MapTask或者MapOutputBuffer的init()方法进行初始化:

设置溢写占比,当使用内存超过一个阈值时就进行溢写,默认为0.8。

设置kvbuffer大小,默认为100M。

通过反射获取sorter对象。

创建kvbuffer,设置equator和其他参数值。

bufstart = bufend = bufindex = equator=0;

bufvoid = kvbuffer.length;

kvstart = kvend = kvindex=bufvoid  -  matasize(16)。

三、环形缓冲区写入数据

1、当执行mapper子类的map()方法调用context.write(key,value)时,最终会调用MapTask的collect(key,value,partition)方法将key,value和meta数据写入上述的kvbuffer。

2、写入一条记录时,首先判断是否满足溢写条件。

3、如果不满足:

(1)、将key序列化存放在bufindex所指向的位置,如果key值被分割在kvbuffer两端;需要调整key位置,使得key连续。并且设定keystart的值。

(3)、执行后bufindex指向下一个空位置。

(4)、将value序列化存放在bufindex指向的位置,并更新bufindex指向下一个空位置;bufindex一直在增加。

(5)、存放meta数据,meta数据占kvbuffer16个字节;用于存放该记录的keystart,valuestart,partition,valuelength信息。

(6)、将meta数据按valuestart,keystart,partition,valuelength顺序存放。 存放完成后kvindex-16;bufstart,bufend,kvstart和kvend不变。

四、溢写

1、在MapTask的collect(key,value,partition)方法往缓冲区存放数据时,判断到达了溢写条件(bufferRemaining-METASIZE <= 0)并且(已使用缓冲区字节数>= softLimit),则进行溢写。

2、当没有达到一些条件,但是文件数据已经读完了,也会触发溢写。

五、注意点

1、配置参数mapreduce.map.sort.spill.percent:溢写占比(默认0.8)。

2、配置参数mapreduce.task.io.sort.mb:kvbuffer大小(默认100M),单位MB。

3、缓冲区最大0x7ffMB,即2047MB。

4、配置参数map.sort.class:溢写时采用的排序对象,默认是QuickSort。

5、写记录(meta,key,value)时,写入meta是(大地址->小地址),而写入key,value是(小地址->大地址);每次写入一条记录,kvindex-16,bufindex+(key,value实际序列化后所需的空间大小);到达kvbuffer边界时进行%运算。

6、value存在key后面(此处时逻辑上的后面,涉及value部分值越过边界放在kvbuffer另一端)。

7、key需要连续存放(在排序中需要对key进行比较需要连续存放),当key值被分开到kvbuffer俩端时,会对key进行一次重新放置,调整后bufvoid会减小。

8、value值可以不连续存放。

9、meta数据占kvbuffer16个字节;用于存放该记录的keystart,valuestart,partition,valuelength信息;将meta数据按valuestart,keystart,partition,valuelength顺序存放。

10、溢写条件:(bufferRemaining-METASIZE <= 0)并且(已使用缓冲区字节数>= softLimit)

11、比较两个meta大小时,首先比较记录的partition值,其次比较key值。

12、在溢写时,首先根据partition和key的值对meta进行排序,使得缓冲区中的meta按partition和key递增排序。在溢写时会重新调整bufvoid的值。

六、本文是自己个人学习总结,同时也借鉴了其他人的优秀文章。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值