腾讯分布式数据仓库(Tencent distributed Data Warehouse, 简称TDW)基于开源软件Hadoop和Hive进行构建,并且根据公司数据量大、计算复杂等特定情况进行了大量优化和改造,目前单集群最大规模达到5600台,每日作业数达到100多万,已经成为公司最大的离线数据处理平台。为了满足用户更加多样的计算需求,TDW也在向实时化方向发展,为用户提供更加高效、稳定、丰富的服务。
TDW计算引擎包括两部分:一个是偏离线的MapReduce,一个是偏实时的Spark,两者内部都包含了一个重要的过程——Shuffle。本文对shuffle过程进行解析,并对两个计算引擎的shuffle过程进行比较,对后续的优化方向进行思考和探索,期待经过我们不断的努力,TDW计算引擎运行地更好。
Shuffle过程介绍
MapReduce的Shuffle过程介绍
Shuffle的本义是洗牌、混洗,把一组有一定规则的数据尽量转换成一组无规则的数据,越随机越好。MapReduce中的shuffle更像是洗牌的逆过程,把一组无规则的数据尽量转换成一组具有一定规则的数据。
为什么MapReduce计算模型需要shuffle过程?我们都知道MapReduce计算模型一般包括两个重要的阶段:map是映射,负责数据的过滤分发;reduce是规约,负责数据的计算归并。Reduce的数据来源于map,map的输出即是reduce的输入,reduce需要通过shuffle来获取数据。
从map输出到reduce输入的整个过程可以广义地称为shuffle。Shuffle横跨map端和reduce端,在map端包括spill过程,在reduce端包括copy和sort过程,如图所示:
Spill过程
Spill过程包括输出、排序、溢写、合并等步骤,如图所示:
Collect
每个Map任务不断地以<key, value>对的形式把数据输出到在内存中构造的一个环形数据结构中。使用环形数据结构是为了更有效地使用内存空间,在内存中放置尽可能多的数据。
这个数据结构其实就是个字节数组,叫kvbuffer,名如其义,但是这里面不光放置了<key, value>数据,还放置了一些索引数据,给放置索引数据的区域起了一个kvmeta的别名,在kvbuffer的一块区域上穿了一个IntBuffer(字节序采用的是平台自身的字节序)的马甲。<key,value>数据区域和索引数据区域在kvbuffer中是相邻不重叠的两个区域,用一个分界点来划分两者,分界点不是亘古不变的,而是每次spill之后都会更新一次。初始的分界点是0,<key, value>数据的存储方向是向上增长,索引数据的存储方向是向下增长,如图所示: