Apache Calcite 功能简析及在 Flink 的应用

Calcite 是什么?

Apache Calcite 是一个动态数据的管理框架,可以用来构建数据库系统的语法解析模块

• 不包含数据存储、数据处理等功能

• 可以通过编写 Adaptor 来扩展功能,以支持不同的数据处理平台

• Flink SQL 使用并对其扩展以支持 SQL 语句的解析和验证

Calcite 谁在用?

下图是一张官方提供的生态系统图,可以看到大名鼎鼎的 Hive、Flink、Druid 以及 Spark、ES 等都可以被纳入 Calcite 生态圈。

Calcite 生态圈

概念解析

Calcite 概念
  1. 关系代数(Relational algebra):即关系表达式。它们通常以动词命名,例如 Sort, Join, Project, Filter, Scan, Sample.
  2. 行表达式(Row expressions):例如 RexLiteral (常量), RexVariable (变量), RexCall (调用) 等,例如投影列表(Project)、过滤规则列表(Filter)、JOIN 条件列表和 ORDER BY 列表、WINDOW 表达式、函数调用等。使用 RexBuilder 来构建行表达式。
  3. 表达式有各种特征(Trait):使用 Trait 的 satisfies() 方法来测试某个表达式是否符合某 Trait 或 Convention.
  4. 转化特征(Convention):属于 Trait 的子类,用于转化 RelNode 到具体平台实现(可以将下文提到的 Planner 注册到 Convention 中). 例如 JdbcConvention,FlinkConventions.DATASTREAM 等。同一个关系表达式的输入必须来自单个数据源,各表达式之间通过 Converter 生成的 Bridge 来连接。
  5. 规则(Rules):用于将一个表达式转换(Transform)为另一个表达式。它有一个由 RelOptRuleOperand 组成的列表来决定是否可将规则应用于树的某部分。
  6. 规划器(Planner) :即请求优化器,它可以根据一系列规则和成本模型(例如基于成本的优化模型 VolcanoPlanner、启发式优化模型 HepPlanner)来将一个表达式转为语义等价(但效率更优)的另一个表达式。

整体模块和处理流程

Catalog – 定义元数据和命名空间,包含 Schema(库)、Table(表)、RelDataType(类型信息)

Catalog 说明

SQL Parser – 将用户编写的 SQL 语句转为 SqlNode 构成的抽象语法树(AST)

  • 通过 JavaCC 模版生成 LL(k) 语法分析器,主模版是 Parser.jj;可对其进行扩展
  • 负责处理各个 Token,逐步生成一棵 SqlNode 组成的 AST
Parser 模板

SQL Validator – 使用 Catalog 中的元数据检验上述 SqlNode AST 并生成 RelNode 组成的 AST

• Query Optimizer – 将 RelNode AST 转为逻辑计划,然后优化它,最终转为实际执行方案。以下是一些常见的优化规则(Rules):

  1. 移除未使用的字段
  2. 合并多个投影(projection)列表
  3. 使用 JOIN 来代替子查询
  4. 对 JOIN 列表重排序
  5. 下推(push down)投影项
  6. 下推过滤条件
优化规则示例: 下推

整体而言,Calcite 处理流程整体可以分为 Parse(语法和语义解析,生成 SqlNode 树)、Validate(验证各对象是否已在 Catalog 中注册)、Optimize(优化、生成 RelNode 树以及物理执行计划)、Execute(具体执行)四个阶段。

流处理语句支持现状

Calcite 支持部分 SQL 流处理语句,也提供了对 Tumbling / Hopping / Sliding / Cascading 等类型 Window 的支持,而 Flink 则把 Window 分为 Tumbling、Sliding (Hopping in SQL)、Session、Global 等类型,与 Calcite 提供的并不完全一致。

目前 Calcite 流处理语句已实现对 SELECT, WHERE, GROUP BY, HAVING, UNION ALL, ORDER BY 以及 FLOOR, CEIL 函数的支持。

其他的操作例如 JOIN, LIMIT 等仍然不支持。具体情况参见 https://calcite.apache.org/docs/stream.html

Flink 与 Calcite

下图是 Flink 系统结构,其中 Table API 与 SQL 模块以 Calcite 为核心,大量用到 Calcite 的各种类和方法。

Flink 系统结构

下图是 Flink Table 模块的内部表示。

可以看到它以 Calcite Catalog 为核心,上面承载了 Table API 和 SQL API 两套表达方式,最后殊途同归,统一生成为 Calcite Logical Plan(SqlNode 树);随后验证、优化为 RelNode 树,最终通过 Rules(规则)和 Convention(转化特征)生成具体的 DataSet Plan(批处理)或 DataStream Plan(流处理),即 Flink 算子构成的处理逻辑。

Flink Table 模块功能图

下图是 SQL 和 Table API 两种表达形式的处理逻辑,上下两种是等价的:

Flink Table API / SQL 转换流程示例

总而言之,Table / SQL API 的编程框架如下

1. 通过 TableEnvironment 配置 CalciteConfig 对象,自动设置 SQL & Table API 默认处理参数。

2. 使用 registerTableSource() 来将一个 TableSource 注册到 rootSchema. 后续可以通过 scan() 获取此 Table 并调用各种 Table API 进行处理。

3. 接下可以调用 sqlQuery() 和 sqlUpdate() 方法来使用 SQL 语句进行数据处理。

运行时 Demo

下面的案例展示了对一句 SQL 查询的中间和最终处理结果:

SQL 语句、生成的 AST、优化后的逻辑计划、最终物理计划
Flink 生成的执行计划

参考阅读

Stream Processing for Everyone with SQL and Apache Flink

Flink 原理与实现:Table & SQL API

Streaming SQL in Apache Flink, KSQL, and Stream Processing for Everyone

Table API & SQL

Introduction to Apache Calcite

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

关于date格式的两个案例(r4笔记第96天)

在工作中总是会碰到各种和date相关的问题,一般这种问题都是让人很纠结的。 比如前几天一个朋友和我分享了他关于时间问题的两个案例。 第一个是他在做impdp导入...

2954
来自专栏Java帮帮-微信公众号-技术文章全总结

Java案例-贪吃蛇小游戏

Java案例-贪吃蛇小游戏 先来看看,这个游戏的截图。 ? 这里可以自定义难度系数(其实就是蛇自己移动的速度),共分10级。这里后面我会说实现方法,这都可以改...

3927
来自专栏搜云库

Spring Boot 中使用 RabbitMQ

一、什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器...

1989
来自专栏程序员叨叨叨

6.4 移位操作符

Cg语言中的移位操作符,功能和C语言中的一样,也可以作用在向量上,但是向量类型必须是int类型。例如:

562
来自专栏Java技术栈

MySQL数据库开发的 36 条军规!

来自一线的实战经验,主要针对DBA和后端开发人员,总是在灾难发生后,才想起容灾的重要性;总是在吃过亏后,才记得曾经有人提醒过。文末是详细的视频讲解和PDF下载。...

785
来自专栏Golang语言社区

【Golang语言社区】H5游戏开发--JavaScript学习:21点游戏

一、游戏规则 21点游戏的规则有很多种,我在写这个21点游戏的时候,选取了一种规则,描述如下: 1、游戏共有两名玩家,玩家1(庄家)和玩家2,在我编写的这个21...

3246
来自专栏PPV课数据科学社区

数据流编程教程:R语言与DataFrame

DataFrame DataFrame 是一个表格或者类似二维数组的结构,它的各行表示一个实例,各列表示一个变量。 一. DataFrame数据流编程 ? 二....

38512
来自专栏腾讯IVWEB团队的专栏

重构代码的Tricks

js的设计模式是针对于整体代码的设计是否合理,给出了一些具体的解决办法。 而重构代码就是依赖于设计模式而实现的一个必要手段,可以说设计模式就是重构代码的目标,但...

2541
来自专栏字根中文校对软件

StreamCQL : 实时计算系统 ( CEP ) 中的持续查询语言 CQL

StreamCQL : 实时计算系统中的持续查询语言 CQL  ( Continuous Query Language )  是一个针对流式数据的查询语言。相对...

2664
来自专栏Crossin的编程教室

编写让别人能读懂的代码

作者:richieyang 随着软件行业的不断发展,历史遗留的程序越来越多,代码的维护成本越来越大,甚至大于开发成本。而新功能的开发又常常依赖于旧代码,阅读旧代...

2998

扫码关注云+社区