这是我参与「第四届青训营 」笔记创作活动的第3天
3. SparkSQL原理解析
3.1 Catalyst优化器
Parsed Logical Plan --> Analyzed Logical Plan --> Optimized Logical Plan --> Physical Plan
3.2 Rule Based Optimizer(RBO)
- Once --> 只执行一次
- FixedPoint --> 重复执行,直到plan不再改变,或者执行达到固定次数(默认100次)
3.3 Adaptive Query Execution(AQE)
- 每个Task结束都会发送MapStatus信息给Driver
- Task的MapStatus中包含当前Task Shuffle产生的每个Partition的size信息
- Driver获取执行完的Stages的MapStatus信息后,按照MapStatus中partition大小信息识别匹配一些优化场景,然后对后续未执行的Plan进行优化。
(1) AQE-Coalescing Shuffle Partitions
Partition合并,优化Shuffle读取,减少reduce task数量
作业运行过程中,根据前面完的Stage的MapStatus中实际的partition大小信息,可以将多个相邻的较小的partition进行动态合并,由一个Task读取处理。
(2) AQE-Sort Merge Join(SMJ) --> Broadcast Hash Join(BHJ)
AQE运行过程中动态获取准确的Join的child/rightchild的实际大小,将SMJ转换为BHJ
(3) AQE-Optimzing Skew Joins
AQE根据MapStatus信息自动检测是否存在倾斜,将大的partition拆分成多个Task进行join。
3.4 Runtime Filter
Runtime Filter减少了大表的扫描,shuffle的数据量以及参加Join的数据量,所以对整个集群IO/网络/CPU有比较大的节省
3.5 Bloom Runtime Filter
3.6 Codegen
(1) Express
将表达式中的大量虚函数调用压平到一个函数内部,类似于手写代码
动态生成代码,Janino即时编译
(2) WholeStageCodegen
算子之间大量的虚函数调用,开销大
考虑将同一个Stage中的多个算子压平到一个函数内部进行执行。
一个SQL包含多个Stage的WholeStageCodegen