Spark SQL 中 Group By 子句的底层实现
Posted
技术标签:
【中文标题】Spark SQL 中 Group By 子句的底层实现【英文标题】:Underlying implementation of Group By clause in Spark SQL 【发布时间】:2019-08-30 03:54:51 【问题描述】:是什么?我知道 Spark 支持两种类型的 Group by 操作,即 GroupByKey 和 ReduceByKey。 ReduceByKey 是一个 map 端 reduce,提供比 GroupByKey 更好的性能。
在我们的应用程序代码中,我们在 Spark Dataframes 上使用 Spark SQL,而不是直接创建 RDD。所以,我想到了这个问题,Spark SQL 中的 GroupBy 是否执行 GroupByKey 或 ReduceByKey 或其他。
【问题讨论】:
【参考方案1】:在 Spark SQL 中,如果你在 agg
内部调用 groupBy(key).agg(...)
并带有一些聚合函数,典型的物理计划是 HashAggregate -> Exchange -> HashAggregate。第一个HashAggregate
负责进行部分聚合(在每个执行器上本地),然后Exchange
代表shuffle,然后第二个HashAggregate
代表shuffle之后的最终聚合(最终合并)。
另请注意,有时HashAggregate
s 可能会被SortAggregate
s 或ObjectHashAggregate
s 替换,具体取决于聚合列的聚合函数和数据类型,但模式保持不变(它们成对出现Exchange
介于两者之间)。
如果数据提前重新分区(可能来自分桶或以前的聚合等),有时Exchange
可能会丢失(没有随机播放)。
【讨论】:
感谢大卫提供此信息。您能否在这方面提供一些来自 Apache Spark 的文档链接。看来我有兴趣进一步阅读。 @Prashant 欢迎您。据我所知,这个 Spark 内部没有很好的文档记录。我自己直接从 Spark 源代码(也从实践中)获得了这些信息。 您在哪里读到有关 Spark 代码的信息?另外,有没有办法在高水平上快速掌握它? (我知道我的问题很笼统)。 @Prashant Spark 源代码可在 github github.com/apache/spark 获得(它是一个开源项目)。它主要是用 Scala 编写的(部分也是用 Java 和 Python 编写的)。可能需要一些时间才能完成,但这取决于您的背景。 所以看起来它确实在洗牌之前在本地聚合了数据,类似于 ReduceByKey,所以性能应该不是问题以上是关于Spark SQL 中 Group By 子句的底层实现的主要内容,如果未能解决你的问题,请参考以下文章
MYSQL,GROUP BY 子句;这与 sql_mode=only_full_group_by [重复] 不兼容
在spark sql中对窗口函数使用having子句的语义是什么?
在 sql 查询中使用 group/order by 和 union 子句
为啥 SQL 强制我在 GROUP BY 子句中重复 SELECT 子句中的所有非聚合字段? [关闭]