MapOutputBuffer理解的三重境界

本文详细探讨了MapReduce中MapOutputBuffer的重要性,从基本认识、运行过程到源码层面进行深入剖析。阐述了MapOutputBuffer的作用、溢写机制以及在数据排序和同步控制上的实现细节,旨在帮助读者全面理解这一关键组件。
摘要由CSDN通过智能技术生成

作者:Lubin Liu


摘要

MapOutputBuffer作为MapTask的内部类,是MR中二次排序非常重要的一环。本文从基本认识,到详细过程,再到源码级别,由浅入深的介绍了这个类。


第一重:基本认识

1.1 MapOutputBuffer是什么?

简而言之,MapOutputBuffer是一个缓存Map输出,并局部排序的类。众所周知,MapReduce从整体上分为Map和Reduce两个阶段,但并不是每个job都必须兼备这两个。
比较简单的job可以只有Map阶段,Map的输出直接写入HDFS提供给用户使用。Reduce阶段,往往意味着数据的重新分配,也就是著名的"shuffle",“shuffle”阶段是根据Map阶段
输出的Key,计算Partition,并交给对应Reduce的过程。在进入“shuffle”阶段之前,我们需要对数据进行初步的排序,并按照partion分组,MapOutputBuffer负责这一过程的。
需要注意的是,这个类只有当job中有Reduce逻辑时才会被调用,因为不需要Reduce,也就没有数据的重新分配,也就没有partition的计算,也就没有排序。

1.2 为什么需要MapOutputBuffer?

从类名上我们可以猜到,这是一个Buffer,buffer的作用一般是为了缓存,那问题变成了为什么要作缓存?难道是仅仅为了累积数据加速写入?我认为不全是。Reduce在拉取数据时,是根据partition的。Map的输入顺序和输出顺序是没有关系的,直接输出的数据是完全乱序的,那拉取时就得把Map输出的数据全部扫一遍,只拿自己partition的,这非常的费时费力。所以设计者想到在写出的时候能不能保证局部有序呢,每次缓存一小部分数据,到一定量的时候,对他们按照partition排序,成块的写入到文件里,拉取的时候方便多了,只要看看哪个partition在哪个块。另一个原因是Combiner,我们知道这个模块是为了减少Shuffle数据量,而在map端局部的执行Reduce逻辑。要想达到这种效果,同样需要缓存和排序,将一个partition的小部分数据排到一起,调用一下Combiner再输出。

1.3 为什么要理解这个类?


首先,几乎每个Job都会自定义自己的partitioner,深刻理解其是怎样作用于数据,可以更好的设计。另外,MR框架提供了很多参数用来调整缓存和排序的行为,因为它深刻的影响了job的性能,更深入的理解有助于懂得如果参数调优。还有,很多job的运行时错误是这个阶段会抛出的,理解的深刻,可以快速定位问题。



第二重:详细理解运行过程

本节详细介绍MapOutputBuffer的运行过程,但只是定性和图解,不会给出源码级别的细节。



2.1 过程简介

MapOutputBuffer类里维护了一个环形缓冲区,每个输出的record都以key value的连同partition信息写入到这个缓冲区中,当缓冲区快满的时候,有一个后台的守护进程负责对数据排序,并写入磁盘。

2.2 主要变量定义

实现一个带meta信息的缓冲区所需变量,有点多,一下记不住没关系,统一列出为了方便查阅。
1. kvbuffer:环形缓冲区,字节数组,用于存储raw数据和meta信息。kvbuffer.length代表数组总长度
2. kvmeta:缓冲区的字节视角,并没有占据新的内存,主要方便插入meta信息。每个meta信息由4个int组成,分布如下

一个metadata的长度是METASIZE=16
3. equator:缓冲区的中界点,raw的key value数据和meta信息分别从中界点往两侧填充。
4. kvindex:下次要插入的meta信息的起始位置
5. kvstart:溢写时meta数据的起始位置

6. kvend:溢写时meta数据的结束位置
7. bufindex:raw数据的结束位置
8. bufstart:溢写时raw数据的起始位置
9. bufend:溢写时raw数据的结束位置
10. spillper:当数据占用超过这个比例,会造成溢写,由配置“mapreduce.map.sort.spill.percent”指定,默认值是0.8
11. sortmb:kvbuffer占用的内存总量,单位是M,由配置“mapreduce.task.index.cache.limit.bytes”指定,默认值是100
12. indexCacheMemoryLimit:存放溢写文件信息的缓存大小,由参数“mapreduce.task.index.cache.limit.bytes”指定,单位是byte,默认值是1024*1024(1M)
13. bufferRemaining:buffer剩余空间,字节为单位
14. softLimit:字节单位的溢写阈值,超过之后需要写磁盘,值等于sortmb*spillper


2.3 初始状态

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值