分享
Flink SQL内部执行流程
输入“/”快速插入内容
Flink SQL内部执行流程
1.
Apache Calcite
Flink Table API & SQL为流式数据和静态数据的关系查询保留统一的接口,而且利用了Apache Calcite的查询优化框架和SQL parser
Flink使用Table API的好处
•
关系型API是声明式的
•
查询能够被有效的优化
•
查询可以高效的执行
•
"Everybody" knows SQL
Calcite是面向Hadoop的sql引擎,提供了标准的SQL语言、多种查询优化和连接各种数据源的能力
1.1
Calcite概念
•
关系代数(Relational algebra)
:关系表达式,通常以动词命名,例如Sort、Join、Project、Filter、Scan、Sample
•
表达式特征(Trait)
:使用Trait的satisfies()方法来测试某个表达式是否符合某Trait或Convention
•
规则(Rules)
:用于将一个表达式转换为另一个表达式,由RelOptRuleOperand组成的列表来决定是否可将规则应用于树的某部分
•
规划器(Planner)
:请求优化器,可根据一系列规则和成本模型(如基于成本优化模型VolcanoPlanner、启发式优化模型HepPlanner)来将一个表达式转换为语义等价的另一个表达式
•
RelNode
:代表了对数据的一个处理操作,常见的操作有Sort、Join、Project、Filter、Scan等。蕴含的是对整个Relation的操作,而不是对具体数据的处理逻辑。RelNode会标识其input RelNode信息,构成一颗RelNode树
RexNode
:行表达式,蕴含的是对一行数据的处理逻辑。每个行表达式都有数据的类型,这是因为在Valdiation的过程中,编译器会推导出表达式的结果类型。常见的行表达式包括字面量Rexliteral,变量RexVariabel,函数或操作符调用RexCall等。RexNode通过RexBuilder进行构建
•
RelTrait
:用来定义逻辑表的物理相关属性(physical property),三种主要的trait类型是:Convention、RelCollation、RelDistribution
1.2
Calcite处理流程
Sql的执行过程一般可分为四个阶段,Calcite分为五个阶段
阶段
抽象
SQL解析阶段,生成AST(抽象语法树)
SQL -> SqlNode
SqlNode验证
SqlNode -> SqlNode
语义分析,生成逻辑计划(Logical Plan)
SqlNode -> RelNode/RexNode
优化阶段,按照相应的规则进行优化
RelNode -> RelNode
生成ExecutionPlan,生成物理执行计划
DataStream Plan
2.
Flink SQL综述
2.1
Flink关系型API执行原理
Flink承载了Table API和SQL API两套表达方式,它以Apache Calcite这个SQL解析器做SQL语义解析,统一生成为Calcite Logical Plan(SqlNode树);随后验证;再利用Calcite的优化器优化转换规则和logical plan,根据数据源的性质(流、批)使用不同的规则进行优化,优化为RelNode逻辑执行计划树;最终优化后的plan转换成常规的Flink DataSet或DataStream程序。任何对于DataStream API和DataSet API的性能调优都能够自动地提示Table API或者SQL查询的效率
2.2
Flink SQL执行流程
一条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去优化logica plan,再基于Flink定制的rules去优化logical Plan
5.
生成Flink PhysicalPlan
:基于Flink里的rules,将optimized LogicalPlan转成Flink的物理执行计划
6.
将物理执行计划转成Flink ExecutionPlan
:调用相应的tanslateToPlan方法转换和利用CodeGen元编程成Flink的各种算子
2.3
Flink Table Api执行流程
通过table api来提交任务,会经过calcite优化等阶段,基本流程和直接运行sql类似
1.
Table api parser
:flink会把table api表达的计算逻辑表示成一颗树,用treeNode去表示,在这棵树上的每个节点的计算逻辑用Expression表示
2.
Validate
:结合数字字典(catalog)将树的每个节点的Unresolved Expression进行绑定,生成Resolved Expression
3.
生成Logical Plan
:依次遍历树的每个节点,调用construct方法将原先用treeNode表达的节点转成用calcite内部的数据结构relNode来表达,生成的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的各种算子