Spark SQL深入分析之图解SortAggregateExec执行流程

前言

从上一篇文章:Spark SQL深入分析之图解Aggregation策略工作流程中我们知道,一个逻辑聚合运算符可以转化为由多个物理聚合阶段组成的物理计划,聚合策略会根据聚合表达式的类型来规划物理聚合计划。

对于每个物理聚合阶段,都会生成一个物理聚合运算符。下图描述了聚合策略选择物理运算符所采用的逻辑。与基于排序的聚合运算符相比,首选基于hash的聚合运算符,因为它不需要额外的排序操作作为先决条件。特别是,HashAggregateExec运算符使用堆外(off-heap)内存存储聚合缓存hash map,从而减少GC时间。

为了符合能够使用HashAggregateExec的条件,从聚合逻辑计划中提取的聚合表达式不能包含任何具有不可变数据类型的aggBufferAttribute。下面是Spark支持的可变数据类型:

如果aggregationExpressions中的任何aggregationFunction是一个TypedImperativeAggregate(使用用户定义的java对象作为内部聚合缓存),并且useObjectHashAggregation标志被设置为true,那么ObjectHashAggregateExec操作符会被选中。

当聚合表达式不符合能够使用HashAggregateExec运算符和ObjectHashAggregateExec运算符的条件时,会选择SortAggregateExec运算符。此外,当基于hash的运算符没有有效的内存时,HashAggregateExec运算符和ObjectHashAggregateExec运算符将回落到使用基于排序的聚合。

本文先对SortAggregateExec进行深入分析,HashAggregateExec和ObjectHashAggregateExec操作符将在下一篇文章中介绍。

SortAggregateExec

SortAggregateExec使用了一种基于排序的聚合方法,该方法要求通过分组键对行进行排序,以便将具有相同分组键的行放置在一起。因此,聚合运算符只需要遍历所有的行,并根据分组键进行聚合。

下面通过图解的方式进一步理解SortAggregateExec操作符是如何工作的。首先,数据集首先需要通过分组键进行reshuffle,使具有相同分组键的行被放置在同一个分区中。在每个分区中,需要通过分组键对行进行排序,以便将具有相同分组键的行放置在一起。

一旦对行进行了排序,聚合操作就可以开始处理行,并进行物理聚合了。在内部,对于每个分区都会创建一个SortBasedAggregationIterator来评估聚合函数。

SortBasedAggregationIterator创建了一个缓存行(buffer row)来缓存聚合的值。不像基于hash的聚合需要一个hash map来保存所有的缓存键值对(如grouping key -> aggregate value),SortBasedAggregationIterator只需要保存当前聚合组的聚合缓存,因此,仅需一行就足够了。当所有aggBufferAttributes的数据类型都是可变的时候,创建的缓存行就会使用堆外内存,否则就使用堆内内存。

当一个分区的SortBasedAggregationIterator实例被构建时,inputIterator参数带来了由上一阶段排序的输入行的迭代器,sortBasedAggregationBuffer将被创建和初始化。

SortBasedAggregationIterator接下来将调用processCurrentSortedGroup方法,该方法开始从输入迭代器中获取要处理的行进行处理,处理完毕后将继续下一个分组的处理(不停迭代直到处理完所有分组键)。

为了更加直观的理解,请看下图:分组键为"1"的行被processCurrentSortedGroup方法逐一处理。对于每一行,processRow方法被调用以使用相应的聚合函数更新缓存的值。在处理完一行后,processCurrentSortedGroup方法检查下一行是否在当前组中,如果存在,就转到这个组的下一行。

当当前分组被处理完毕,就会产生当前分组的输出行。

然后聚合缓存将被重置,以处理下一个分组键。

这个过程将重复进行,直到所有的输入行都被处理完毕。

总结

本文主要通过图文的形式直观的展示了SortAggregateExec策略聚合过程的工作原理,下一篇文章将继续探讨其余聚合策略,敬请关注。

- THE END -

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值