MapReduce shuffle过程剖析及调优

更新记录

  • 2017-07-18 初稿

MapReduce简介

在Hadoop MapReduce中,框架会确保reduce收到的输入数据是根据key排序过的。数据从Mapper输出到Reducer接收,是一个很复杂的过程,框架处理了所有问题,并提供了很多配置项及扩展点。一个MapReduce的大致数据流如下图:

这里写图片描述

更详细的MapReduce介绍参考Hadoop MapReduce原理与实例

Mapper的输出排序、然后传送到Reducer的过程,称为shuffle。本文详细地解析shuffle过程,深入理解这个过程对于MapReduce调优至关重要,某种程度上说,shuffle过程是MapReduce的核心内容。

Mapper端

当map函数通过context.write()开始输出数据时,不是单纯地将数据写入到磁盘。为了性能,map输出的数据会写入到缓冲区,并进行预排序的一些工作,整个过程如下图:

这里写图片描述

环形Buffer数据结构

每一个map任务有一个环形Buffer,map将输出写入到这个Buffer。环形Buffer是内存中的一种首尾相连的数据结构,专门用来存储Key-Value格式的数据:

这里写图片描述

Hadoop中,环形缓冲其实就是一个字节数组:

// MapTask.java
private byte[] kvbuffer;  // main output buffer

kvbuffer = new byte[maxMemUsage - recordCapacity]; 

kvbuffer包含数据区和索引区,这两个区是相邻不重叠的区域,用一个分界点来标识。分界点不是永恒不变的,每次Spill之后都会更新一次。初始分界点为0,数据存储方向为向上增长,索引存储方向向下:

这里写图片描述

bufferindex一直往上增长,例如最初为0,写入一个int类型的key之后变为4,写入一个int类型的value之后变成8。

索引是对key-value在kvbuffer中的索引,是个四元组,占用四个Int长度,包括:

  • value的起始位置
  • key的起始位置
  • partition值
  • value的长度
private static final int VALSTART = 0;    // val offset in acct
private static final int KEYSTART = 1;    // key offset in acct
private static final int PARTITION = 2;   // partition offset in acct
private static final int VALLEN = 3;      // length of value
private static final int NMETA = 
  • 22
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值