1. SparkSQL的自动优化
我们前面的文章已经说过spark RDD定义好后,执行经过DAG sechduler划分号内存管道、逻辑任务,然后经由task scheduler来分配到具体worker来管理运行,RDD的运行会完全按照开发者的代码执行
如果开发者水平有限,RDD的执行效率也会受到影响。
而SparkSQL会对写完的代码,执行自动优化”,以提升代码运行效率,避免开发者水平影响到代码执行效率。之所以RDD的的执行没法被优化,市因为RDD内含数据类型不限格式和结构,而DataFrame100%是二维表结构,可以被针对,SparkSQL的自动优化依赖于Catalyst优化器,它最终也是被优化成RDD来执行。
2. Catalyst优化器
为了解决过多依赖Hive的问题,SparkSQL使用了一个新的SQL优化器替代Hive中的优化器,这个优化器就是Catalyst,整个SparkSQL的架构大致如下:
- APl层简单的说就是Spark会通过一些AP接受SQL语句
- 收到SQL语句以后,将其交给Catalyst,Catalyst负责解析SQL,生成执行计划等
- Catalyst的输出应该是RDD的执行计划
- 最终交由集群运行
详细的流程如下:
- 第一步解析sql语句为抽象语法树
catalyst第一步会将sql语句解析成抽象语法树,上面的语法树是从下往上看的
- 第二步会给抽象语法树加上一些元数据信息方便spark去调用和优化相关信息
- 第三步做优化
优化操作主要分两步:
(1)断言下推Predicate Pushdown
这一步会将将Filter或一些判断过滤类的可以减小数据集的操作下推,放在Scan的位置,这样可以减少操作时候的数据量。
SELECT sum(v)
FROM(
SELECT
score.id
100 + 80 + score.math_score AS v
FROM people
JOIN score WHERE people.id = score.id AND people.age > 10
)omp
如这个代码,正常流程是先JOIN然后做WHERE
断言下推后,会先过滤age,然后在JOIN,减少JOIN的数据量提高性能.
(2) 列值裁剪Column Pruning,在断言下推后执行裁剪,由于people表之上的操作只用到了id列,所以可以把其它列裁剪掉,这样可以
减少处理的数据量,从而优化处理速度,列值裁剪很适合parquet这种列值存储数据
- 第四步
上面的过程生成的AST其实最终还没办法直接运行,这个AST叫做逻辑计划,结束后,需要生成物理计划,从而生成RDD来运行,在生成物理计划的时候,会经过成本模型对整棵树再次执行优化,选择一个更好的计划,在生成物理计划以后,因为考虑到性能,所以会使用代码生成,在机器中运行,可以使用queryExecution方法查看逻辑执行计划使用explain方法查看物理执行计划
3. sparksql执行流程总结
- 提交SparkSQL代码
- catalyst优化
a.生成原始AST语法数
b.标记AST元数据
c.进行断言下推和列值裁剪以及其它方面的优化作用在AST上
d.将最终AST得到,生成执行计划
e.将执行计划翻译为RDD代码 - Driver执行环境入口构建(SparkSession)
- DAG调度器规划逻辑任务
- TASK调度区分配逻辑任务到具体Executor_上工作并监控管理任务
- Worker干活.