Spark SQL运行原理和架构(十一)

一、Spark SQL运行架构

Spark SQL对SQL语句的处理和关系型数据库类似,即词法/语法解析、绑定、优化、执行。Spark SQL会先将SQL语句解析成一棵树,然后使用规则(Rule)对Tree进行绑定、优化等处理过程。

1. Spark SQL模块

Spark SQL模块

Spark SQL模块划分为Core、caralyst、hive和hive- ThriftServer四大模块。
Core: 负责处理数据的输入和输出,如获取数据,查询结果输出成DataFrame等。
Catalyst: 负责处理整个查询过程,包括解析、绑定、优化等。
Hive: 负责对Hive数据进行处理。
Hive-ThriftServer: 主要用于对hive的访问。

catalyst设计图

注意:图中的虚线部分是现在未实现或实现不完善的。
其中虚线部分是以后版本要实现的功能,实线部分是已经实现的功能。

2. Spark SQL运行原理

使用SessionCatalog保存元数据:
在解析SQL语句之前,会创建SparkSession,或者如果是2.0之前的版本初始化SQLContext,SparkSession只是封装了SparkContext和SQLContext的创建而已。会把元数据保存在SessionCatalog中,涉及到表名,字段名称和字段类型。创建临时表或者视图,其实就会往SessionCatalog注册。

1)SqlParse: 基于antlr框架对 sql解析,生成抽象语法树;

当调用SparkSession的sql或者SQLContext的sql方法,我们以2.0为准,就会使用SparkSqlParser进行解析SQL. 使用的ANTLR进行词法解析和语法解析。它分为2个步骤来生成Unresolved LogicalPlan:
词法分析:Lexical Analysis,负责将token分组成符号类
构建一个分析树或者语法树AST

2)Analyzer: 主要完成绑定工作,将不同来源的Unresolved LogicalPlan和元数据(如hive metastore、Schema catalog)进行绑定,生成resolved LogicalPlan;

在该阶段,Analyzer会使用Analyzer Rules,并结合SessionCatalog,对未绑定的逻辑计划进行解析,生成已绑定的逻辑计划。

3)optimizer: 对resolvedLogicalPlan进行优化,生成optimizedLogicalPlan(OptimizationRules,对resolvedLogicalPlan进行合并、列裁剪、过滤器下推等优化作业而转换成optimized LogicalPlan);

优化器也是会定义一套Rules,利用这些Rule对逻辑计划和Exepression进行迭代处理,从而使得树的节点进行合并和优化。

4)Planner: 将LogicalPlan转换成PhysicalPlan;

SparkSpanner使用Planning Strategies,对优化后的逻辑计划进行转换,生成可以执行的物理计划SparkPlan.

5)CostModel: 主要根据过去的性能统计数据,选择最佳的物理执行计划。

此时调用SparkPlan的execute方法,底层其实已经再触发JOB了,然后返回RDD。

3. Spark SQL运行架构

类似于关系型数据库,SparkSQL也是语句也是由Projection(a1,a2,a3)、DataSource(tableA)、Filter(condition)组成,分别对应sql查询过程中的Result、Data Source、Operation,也就是说SQL语句按Result-->Data Source-->Operation的次序来描述的。


Spark SQL运行架构

执行SparkSQL语句顺序为:
1.对读入的SQL语句进行解析(Parse),分辨出SQL语句中哪些词是关键词(如SELECT、FROM、WHERE),哪些是表达式、哪些是Projection、哪些是Data Source等,从而判断SQL语句是否规范;
2.将SQL语句和数据库的数据字典(列、表、视图等等)进行绑定(Bind),如果相关的Projection、DataSource等都是存在的话,就表示这个SQL语句是可以执行的;
3.一般的数据库会提供几个执行计划,这些计划一般都有运行统计数据,数据库会在这些计划中选择一个最优计划(Optimize);
4.计划执行(Execute),按Operation-->DataSource-->Result的次序来进行的,在执行过程有时候甚至不需要读取物理表就可以返回结果,比如重新运行刚运行过的SQL语句,可能直接从数据库的缓冲池中获取返回结果。

推荐阅读更多精彩内容