常见的一些大数据计算框架,例如Hive、spark SQL、flink SQL都是将SQL转换为对应框架的计算结构执行作业的,此文汇总一下各个框架的底层对于SQL的转换的架构或者原理,内容均来自各个平台各个博客的摘录,原链接会贴在最后,如有摘录但是未贴出原链接请见谅,联系我会进行删改。谢谢。
Hive
hive架构图:
可以看出,hive本身不执行作业,将SQL转换为执行计划然后交由MapReduce执行。
hive将SQL转换为mapreduce任务主要分为6步:
- 词法、语法解析: Antlr 定义 SQL 的语法规则,完成 SQL 词法,语法解析,将 SQL 转化为抽象语法树 AST Tree;
- 语义解析: 遍历 AST Tree,抽象出查询的基本组成单元 QueryBlock;
- 生成逻辑执行计划: 遍历 QueryBlock,翻译为执行操作树 OperatorTree;
- 优化逻辑执行计划: 逻辑层优化器进行 OperatorTree 变换,合并 Operator,达到减少 MapReduce Job,减少数据传输及 shuffle 数据量;
- 生成物理执行计划: 遍历 OperatorTree,翻译为 MapReduce 任务;
- 优化物理执行计划: 物理层优化器进行 MapReduce 任务的变换,生成最终的执行计划。
对上述进行细化:
- 进入程序,利用Antlr框架定义的HQL语法规则,对HQL完成词法语法解析,将HQL转换为AST(抽象语法树)
- 遍历AST,抽象出查询的基本组成单元QueryBlock(查询块),可以理解为最小的查询执行单元
- 遍历QueryBlock,将其转换为OperatorTree(操作树,也就是逻辑执行计划),可以理解为不可拆分的一个逻辑执行单元
- 使用逻辑优化器对OperatorTree进行逻辑优化。例如合并不必要的reduceSinkOperator,减少shuffle数据量
- 遍历OperatorTree,转换为TaskTree。也就是翻译为MR任务的流程,将逻辑执行计划转换为物理执行计划
- 使用物理优化器对TaskTree进行物理优化
- 生成最终的执行计划,提交任务到Hadoop集群运行
HiveSQL转化MR执行流程
HiveSQL->AST(抽象语法树)->QB(查询块)->OperatorTree(操作树)->优化后的操作树->mapreduce任务树->优化后的mapreduce任务树
spark SQL
spark SQL底层架构:
可以看到spark的SQL语句经过catalyst转换RDD了,再交由cluster执行。
Catalyst,它就是Spark SQL的核心,是针对Spark SQL语句执行过程中的查询优化框架,基于Scala函数式编程结构。
一条SQL语句生成执行引擎可识别的程序,就离不开解析(Parser)、优化(Optimizer)、执行(Execution) 这三大过程。而Catalyst优化器在执行计划生成和优化的工作时候,它离不开自己内部的五大组件,如下所示:
- Parser模块:将SparkSql字符串解析为一个抽象语法树/AST。
- Analyzer模块:该模块会遍历整个AST,并对AST上的每个节点进行数据类型的绑定以及函数绑定,然后根据元数据信息Catalog对数据表中的字段进行解析。
- Optimizer模块:该模块是Catalyst的核心,主要分为RBO和CBO两种优化策略,其中RBO是基于规则优化,CBO是基于代价优化。
- SparkPlanner模块:优化后的逻辑执行计划OptimizedLogicalPlan依然是逻辑的,并不能被Spark系统理解,此时需要将OptimizedLogicalPlan转换成physical plan(物理计划) 。
- CostModel模块:主要根据过去的性能统计数据,选择最佳的物理执行计划。这个过程的优化就是CBO(基于代价优化)。
Flink SQL
Flink SQL 引擎的工作流总结如图所示:
从图中可以看出,一段查询 SQL / 使用TableAPI 编写的程序从输入到编译为可执行的 JobGraph 主要经历如下几个阶段:
- 将 SQL文本 / TableAPI 代码转化为逻辑执行计划(Logical Plan)
- Logical Plan 通过优化器优化为物理执行计划(Physical Plan)
- 通过代码生成技术生成 Transformations 后进一步编译为可执行的 JobGraph 提交运行
一条stream sql从提交到calcite解析、优化最后到flink引擎执行,一般分为以下几个阶段:
- Sql Parser: 将sql语句通过java cc解析成AST(语法树),在calcite中用SqlNode表示AST;
- Sql Validator: 结合数字字典(catalog)去验证sql语法;
- 生成Logical Plan: 将sqlNode表示的AST转换成LogicalPlan, 用relNode表示;
- 生成 optimized LogicalPlan: 先基于calcite rules 去优化logical Plan,
再基于flink定制的一些优化rules去优化logical Plan; - 生成Flink PhysicalPlan: 这里也是基于flink里头的rules,将optimized LogicalPlan转成成Flink的物理执行计划;
- 将物理执行计划转成Flink ExecutionPlan: 就是调用相应的tanslateToPlan方法转换和利用CodeGen元编程成Flink的各种算子。
PS: flink SQL中使用的是calcite对SQL进行解析,好像Hive也是。
总结
从上述的架构图来看,hive SQL、spark SQL、Flink SQL底层架构都具有一定的相似性,都是将SQL转换为AST(语法抽象树),然后再经过优化转换为物理执行计划,最后再交由下游去处理执行。
原文博客链接
Hive
cloud.tencent.com/developer/a…
cloud.tencent.com/developer/a…
spark SQL
cloud.tencent.com/developer/a…