Spark SQL系列------2. Spark SQL Aggregate操作的实现

 在Spark 1.6上,TungstenAggregateIterator实现了一个分区的Iterator。在实际执行的时候分2中情况:

1.要Aggregate的分区数据并不是特别大,在内存中就可以实现Aggregate了

2.要Aggregate的分区数据比较大,在内存中已经不能实现Aggregate,则需要将内存的数据Partial累加之后,spill到磁盘。


Aggregate操作的原理是对table中的某个field,根据某种累加规则进行累加。并且将累加结果存放到内存或者磁盘,如下图所示:


原始数据先根据Aggregate方法和属性生成Aggregate中间结果,Aggregate中间结果再根据结果表达式,计算出Aggregate输出结果。

Spark在执行Aggregate操作的时候,如果分区数据并不是特别大,数据在内存中的存储可以用如下图表示:



BytesToBytesMap.longArray这个大数组存储了Aggregate的中间结果存放的位置。

keyAddress是TaskMemoryManager.encodePageNumberAndOffset方法根据Aggregate中间结果所在的MemoryPage的index和在MemoryPage的偏移量计算出来的。BytesToBytesMap.longArray中的hashcode是根据Aggregate的Key值计算出来的。hashcode主要用于快速查找某个Key是不是已经有Aggregate中间结果了。

在MemoryPage是一块连续的内存,里面存储了Aggregate的中间结果,MemoryPage的recordsInPage(前4个字节)记录这一页存储了多少个中间结果。

1个Aggregate中间结果内容分4个部分:

keylen+valuelen+4  表示中间结果中Aggregate key的长度加上Aggregate后value的长度

keylen   表示key的长度

key的值

value的值

Spark在进行Aggregate的时候,会根据这种存储形式进行Aggregate中间数据的读取和存储。

如果内存足够大,不需要外部排序,这个时候可以将MemoryPage中的数据转化成Iterator,就可以产生结果数据了。Iterator和Aggregate内存存储数据之间的对应关系为:


可见Iterator的数据顺序和在MemoryPage中数据的存储数据是一致的。

由于需要Aggregate的数据太大,在内存中已经无法实现Aggregate,则需要进行外部排序Aggregate。流程如下图所示:



在这个时候,内存中只能进行Partial Aggregate,并且需要将内存的数据排序之后再spill到磁盘,然后跟之前已经spill到磁盘的Aggregate中间结果进行merge。这步merge操作所作的工作是将两个Iterator进行排序合并。这样相同Key的数据在最终的Iterator中就连续再一起了。在产生输出结果的时候,可以调用TungstenAggregator.processCurrentSortedGroup方法,对已经进行Partial Aggregate的中间结果进行ParitialMerge处理了。

数据spill到磁盘之后,存储Aggregate中间结果的的内存会全部释放。

从以上的分析流程可以知道,当内存不够需要将数据排序之后再spill到磁盘,但是在进行排序的时候并没有额外分配内存,而是使用BytesToBytesMap.longArray。排序之后BytesToBytesMap.longArray的数据是有序的,存储了中间结果的顺序,然后按照这个顺序,将Aggregate中间结果spill到磁盘。spill之前BytesToBytesMap.longArray的数据和MemoryPage中中间结果之间的对应关系可以用如下图表示:



从以上分析可知道,Aggregate的时候进行外部排序对性能的影响是很大的,数据需要落地到磁盘,并且还需要从磁盘中加载数据进行Merge,输出结果。


以上是对Spark1.6 TungstenAggregateIterator的分析,可能存在问题,希望其它同学指正。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值