目录
一、SparkSql执行过程基本要点
二、SparkSql解析流程
三、Hive on spark的内部实现机制
四、其他问题
一、SparkSql执行过程基本要点
现有下面这段SQL语句
SELECT a.uid,b.name,SUM(clk_pv) AS clk_pv
FROM log a
JOIN user b ON a.uid = b.uid
WHERE a.fr = 'android'
GROUP BY a.uid,b.name
这段SQL是从日志表中拿出用户点击PV(clk_pv),再去和用户表关联,按照用户分组,再对点击pv求和,同时,还过滤了fr(平台)是android的数据,;这样一条SQL在Spark中或者说在数据库引擎中如何运行?
首先,有几个基本点:
- 所有的编程语言,都是基于操作系统执行。都会被编译(如Java)或被解释(如Python)为操作系统能够按照一定次序执行的命令
- SQL不同于其他编程语言,它是构造在数据库引擎之上的,而数据库引擎又是构造在操作系统之上的,所以,SQL执行的过程是编译成数据库引擎能执行的最优的命令
- 对于用户输入的SQL文本,数据库引擎是通过一种交AST(抽象语法树)进行解析的,实际上是做语法分析
- AST分析目前有很多实现,一种典型的开源实现是ANLTR. Spark SQL 使用的是ANLTRV4 这个版本。
二、SparkSql解析流程
SQL解析的顺序
SQL 文本 ---> ANLTRV4解析器-->未解析的逻辑计划 ---> 分析器 -->解析后的逻辑计划---> 优化器 -->优化后的逻辑计划 ---> 转换器 -->可执行的物理计划
SQL解析的思路
解析器的目的是将用户输入的文本,按照预置的关键词,语义等规则解析成一棵 AST。 后续,分析器、优化器,转化器,可对这棵树的节点按照规则遍历,并转换节点结构。
如上图,每个模块都可以理解为,对第一步产生的AST做节点变化操作。
对于最开始提出的SQL,第一步参数的未解析的逻辑计划如下:
这棵语法数的叶子节点是我们查的两张表,log,user,在往上一层,可看到,实际上是将我们的关联查询解析为两个子查询,再往上一次,是对这两个子查询做join,并按照匹配条件过滤,最后是按照我们所要的聚合条件做聚合投影(projection)
三、Hive on spark的内部实现机制
1. Hive流程
- 语法分析阶段,Hive利用Antlr将用户提交的SQL语句解析成一棵抽象语法树(Abstract Syntax Tree,AST)。
- 生成逻辑计划包括通过Metastore获取相关的元数据,以及对AST进行语义分析。得到的逻辑计划为一棵由Hive操作符组成的树,Hive操作符即Hive对表数据的处理逻辑,比如对表进行扫描的TableScanOperator,对表做Group的GroupByOperator等。
- 逻辑优化即对Operator Tree进行优化,与之后的物理优化的区别主要有两点:一是在操作符级别进行调整;二是这些优化不针对特定的计算引擎。比如谓词下推(Predicate Pushdown)就是一个逻辑优化:尽早的对底层数据进行过滤以减少后续需要处理的数据量,这对于不同的计算引擎都是有优化效果的。
- 生成物理计划即针对不同的引擎,将Operator Tree划分为若干个Task,并按照依赖关系生成一棵Task的树(在生成物理计划之前,各计算引擎还可以针对自身需求,对Operator Tree再进行一轮逻辑优化)。比如,对于MapReduce,一个GROUP BY+ORDER BY的查询会被转化成两个MapReduce的Task,第一个进行Group,第二个进行排序。
- 物理优化则是各计算引擎根据自身的特点,对Task Tree进行优化。比如对于MapReduce,Runtime Skew Join的优化就是在原始的Join Task之后加入一个Conditional Task来处理可能出现倾斜的数据。
- 最后按照依赖关系,依次执行Task Tree中的各个Task,并将结果返回给用户。每个Task按照不同的实现,会把任务提交到不同的计算引擎上执行。
2. Hive on spark解析SQL的过程
SQL
SQL语句在分析执行过程中会经历下图所示的几个步骤
- 语法解析
- 操作绑定
- 优化执行策略
- 交付执行
语法解析
语法解析之后,会形成一棵语法树,如下图所示。树中的每个节点是执行的rule,整棵树称之为执行策略。
四、其他问题
- SparkSQL 执行DDL和DML由何区别
- DataFrameWriter执行流程和SQL(create table as select )建表有和不同