最近想来,大数据相关技术与传统型数据库技术很多都是相互融合、互相借鉴的。传统型数据库强势在于其久经考验的sql优化器经验,弱势在于分布式领域的高可用性、容错性、扩展性等,假以时日,让其经过一定的改造,比如引入Paxos、raft等,强化自己在分布式领域的能力,相信一定会在大数据系统中占有一席之地。相反,大数据相关技术优势在于其天生的扩展性、可用性、容错性等,但其sql优化器经验却基本全部来自于传统型数据库,当然,针对列式存储大数据sql优化器会有一定的优化策略。
spark sql 设计框架大致可以分为 3 层
api 层,sql + dataframe + dataset,通过 api 接收 sql 语句,
计划层,Catalyst 优化器,解析 sql 生成执行计划
执行层,rdd、dag 物理计划 + rm 、scheduler + tungsten 底层优化,生成 rdd 组成的 dag 执行计划交由集群执行
Catalyst 主要是计划层做优化,其运作原理是分为四步, 先对 sql 或者 Dataset 的代码解析, 生成逻辑计划, 后对逻辑计划进行优化, 再生成物理计划, 最后生成代码到集群中以 RDD 的形式运行。
parser 解析器 :解析 sql,生成抽象语法树(AST);
analyser 分析器 :在 AST 中加入元数据信息, 即数据类型绑定以及函数绑定;
logical optimization 逻辑优化 :对已经加入元数据的 AST, 输入优化器进行优化,比如,谓词下推、列值裁剪、固定精度、常量累加、Limits合并;
physical planning 物理计划 :`成本模型`对整棵树再次执行优化, 选择一个更好的计划;
code generation 代码生成 :quasiquotes 允许用 scala 语言编程构建抽象语法树(AST),然后可以在运行时将其提供给scala编译器以生成字节码。
- 备注 :可以使用 queryExecution 方法查看逻辑执行计划, 使用 explain 方法查看物理执行计划,也可以使用 spark WebUI 在 sql 标签下查看这两个计划
AST
Catalyst 的主要数据类型就是有节点对象组成的树。每个node都有一个node类型和零个或者多个子节点。scala中新定义的node类型是TreeNode类的子类。这些对象都是不可改变的,可以使用函数转换来操作。
举一个简单的例子,针对一个非常简单的expression我们总共有下面三种node类型:
A),Literal(value: Int): 一个常量
B),Attribute(name: String):输入行的一个列属性,例如:“x”
C),Add(left: TreeNode, right: TreeNode):两个expressions求加
这些类可以用来构建一棵树。举例,x+(1+2),这个表达式,在scala代码中就如下:
Add(Attribute(x), Add(Literal(1), Literal(2)))
analyzer
analyzer 遍历整个AST,对树上的每个节点进行数据类型绑定以及函数绑定,比如people词素会根据元数据表信息解析为包含age、id以及name三列的表,people.age会被解析为数据类型为int的变量,sum会被解析为特定的聚合函数,
optimization
逻辑优化是使用规则来操纵树,这些规则是从一颗树到另一棵树的转换函数。虽然一个规则可以在其输入树上运行任意代码(给定这个树只是一个scala对象),但最常见的方法是使用一组模式匹配函数来查找和替换子树为特定结构。模式匹配是许多函数编程语言的特征,允许从代数数据类型的潜在嵌套结构中提取值。在Catalyst中,语法树提供了一种转换方法,可以在树的所有节点上递归地应用模式匹配函数,将匹配到的节点转换为特定结果。
planning
在物理计划层,spark sql会获取一个逻辑计划,用物理操作算子产生一个或者多个物理计划。然后用cost模型选择一个物理计划。目前基于cost-based的优化仅仅用于选择join算法:对已知的很小的relations,spark sql会选择使用spark的提供的点对点的广播功能实现Broadcast join。该框架支持更广泛地使用cost-based的优化,然而,由于可以使用规则为整个树递归地估计成本。因此,我们打算在未来实现更加丰富的cost-based优化。
物理计划还可以执行基于规则的物理优化,比如将列裁剪和过滤操在一个spark的Map算子中以pipeline方式执行。此外,它可以将逻辑计划的操作下推到支持谓词或projection 下推的数据源。
在物理计划层,Catalyst也许会产生多个物理计划,然后根据cost进行选择。其它,层都是单纯的基于规则的优化。每个层使用不同的树节点类型。Catalyst 拥有的节点库包括表达式(expressions),数据类型(data types),逻辑和物理操作(logical and physical operators)。
Catalyst 启蒙篇
http://hbasefly.com/2017/03/01/sparksql-catalyst/?sofqze=clzgb1&juneng=r8eoa1
图表抽象表达清晰的 spark sql Catalyst 优化器
https://blog.csdn.net/qq_18800463/article/details/101194101
https://www.jianshu.com/p/410c23efb565
spark sql 优化器 Catalyst 综述性文章,后者包括 spark sql 的源码链接
https://cloud.tencent.com/developer/article/1032529
https://juejin.im/entry/5b3b202ce51d45191c7e10b5
spark sql 自定义优化器的实现, cost 模型的详细步骤
https://my.oschina.net/freelili/blog/3001238