浅析大数据计算框架的SQL底层原理

791 阅读5分钟

常见的一些大数据计算框架,例如Hive、spark SQL、flink SQL都是将SQL转换为对应框架的计算结构执行作业的,此文汇总一下各个框架的底层对于SQL的转换的架构或者原理,内容均来自各个平台各个博客的摘录,原链接会贴在最后,如有摘录但是未贴出原链接请见谅,联系我会进行删改。谢谢。

Hive

hive架构图:

image.png 可以看出,hive本身不执行作业,将SQL转换为执行计划然后交由MapReduce执行。

hive将SQL转换为mapreduce任务主要分为6步:

image.png

  1. 词法、语法解析: Antlr 定义 SQL 的语法规则,完成 SQL 词法,语法解析,将 SQL 转化为抽象语法树 AST Tree;
  2. 语义解析: 遍历 AST Tree,抽象出查询的基本组成单元 QueryBlock;
  3. 生成逻辑执行计划: 遍历 QueryBlock,翻译为执行操作树 OperatorTree;
  4. 优化逻辑执行计划: 逻辑层优化器进行 OperatorTree 变换,合并 Operator,达到减少 MapReduce Job,减少数据传输及 shuffle 数据量;
  5. 生成物理执行计划: 遍历 OperatorTree,翻译为 MapReduce 任务;
  6. 优化物理执行计划: 物理层优化器进行 MapReduce 任务的变换,生成最终的执行计划。

对上述进行细化:

image.png

  1. 进入程序,利用Antlr框架定义的HQL语法规则,对HQL完成词法语法解析,将HQL转换为AST(抽象语法树)
  2. 遍历AST,抽象出查询的基本组成单元QueryBlock(查询块),可以理解为最小的查询执行单元
  3. 遍历QueryBlock,将其转换为OperatorTree(操作树,也就是逻辑执行计划),可以理解为不可拆分的一个逻辑执行单元
  4. 使用逻辑优化器对OperatorTree进行逻辑优化。例如合并不必要的reduceSinkOperator,减少shuffle数据量
  5. 遍历OperatorTree,转换为TaskTree。也就是翻译为MR任务的流程,将逻辑执行计划转换为物理执行计划
  6. 使用物理优化器对TaskTree进行物理优化
  7. 生成最终的执行计划,提交任务到Hadoop集群运行

HiveSQL转化MR执行流程

HiveSQL->AST(抽象语法树)->QB(查询块)->OperatorTree(操作树)->优化后的操作树->mapreduce任务树->优化后的mapreduce任务树

spark SQL

spark SQL底层架构:

image.png 可以看到spark的SQL语句经过catalyst转换RDD了,再交由cluster执行。 Catalyst,它就是Spark SQL的核心,是针对Spark SQL语句执行过程中的查询优化框架,基于Scala函数式编程结构。 一条SQL语句生成执行引擎可识别的程序,就离不开解析(Parser)、优化(Optimizer)、执行(Execution) 这三大过程。而Catalyst优化器在执行计划生成优化的工作时候,它离不开自己内部的五大组件,如下所示:

Pasted image 20240514153959.png

  1. Parser模块:将SparkSql字符串解析为一个抽象语法树/AST。
  2. Analyzer模块:该模块会遍历整个AST,并对AST上的每个节点进行数据类型的绑定以及函数绑定,然后根据元数据信息Catalog对数据表中的字段进行解析。
  3. Optimizer模块:该模块是Catalyst的核心,主要分为RBO和CBO两种优化策略,其中RBO是基于规则优化,CBO是基于代价优化
  4. SparkPlanner模块:优化后的逻辑执行计划OptimizedLogicalPlan依然是逻辑的,并不能被Spark系统理解,此时需要将OptimizedLogicalPlan转换成physical plan(物理计划)
  5. CostModel模块:主要根据过去的性能统计数据,选择最佳的物理执行计划。这个过程的优化就是CBO(基于代价优化)。

Flink SQL

Flink SQL 引擎的工作流总结如图所示:

image.png 从图中可以看出,一段查询 SQL / 使用TableAPI 编写的程序从输入到编译为可执行的 JobGraph 主要经历如下几个阶段:

  1. 将 SQL文本 / TableAPI 代码转化为逻辑执行计划(Logical Plan)
  2. Logical Plan 通过优化器优化为物理执行计划(Physical Plan)
  3. 通过代码生成技术生成 Transformations 后进一步编译为可执行的 JobGraph 提交运行

一条stream sql从提交到calcite解析、优化最后到flink引擎执行,一般分为以下几个阶段:

  1. Sql Parser: 将sql语句通过java cc解析成AST(语法树),在calcite中用SqlNode表示AST;
  2. Sql Validator: 结合数字字典(catalog)去验证sql语法;
  3. 生成Logical Plan: 将sqlNode表示的AST转换成LogicalPlan, 用relNode表示;
  4. 生成 optimized LogicalPlan: 先基于calcite rules 去优化logical Plan,
    再基于flink定制的一些优化rules去优化logical Plan;
  5. 生成Flink PhysicalPlan: 这里也是基于flink里头的rules,将optimized LogicalPlan转成成Flink的物理执行计划;
  6. 将物理执行计划转成Flink ExecutionPlan: 就是调用相应的tanslateToPlan方法转换和利用CodeGen元编程成Flink的各种算子。

PS: flink SQL中使用的是calcite对SQL进行解析,好像Hive也是。

总结

从上述的架构图来看,hive SQL、spark SQL、Flink SQL底层架构都具有一定的相似性,都是将SQL转换为AST(语法抽象树),然后再经过优化转换为物理执行计划,最后再交由下游去处理执行。

image.png


原文博客链接

Hive

cloud.tencent.com/developer/a…

cloud.tencent.com/developer/a…

spark SQL

cloud.tencent.com/developer/a…

zhuanlan.zhihu.com/p/58428916

Flink SQL

developer.aliyun.com/article/765…

blog.csdn.net/super_wj082…