前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flink】第二十八篇:Flink SQL 与 Apache Calcite

【Flink】第二十八篇:Flink SQL 与 Apache Calcite

作者头像
章鱼carl
发布2022-03-31 11:22:09
2.1K0
发布2022-03-31 11:22:09
举报
文章被收录于专栏:章鱼carl的专栏章鱼carl的专栏

源码分析系列推荐:

【Flink】第四篇:【迷思】对update语义拆解D-、I+后造成update原子性丢失

【Flink】第十五篇:Redis Connector 数据保序思考

【Flink】第十六篇:源码角度分析 sink 端的数据一致性

【Flink】第二十四篇:源码角度分析 DataStream API 调用逻辑

【Flink】第二十五篇:源码角度分析作业提交逻辑

【Flink】第二十六篇:源码角度分析Task执行过程

【Flink】第二十七篇:三天撸了一个 Flink SQL 字段血缘算法

接上篇 【Flink】第二十七篇:三天撸了一个 Flink SQL 字段血缘算法 ,从本篇开始深入Flink SQL的解析流程及原理。

本文内容:

  1. Apache Calcite介绍
  2. 从源码工程中一瞥Flink SQL中的Calcite

DSL & GPL

通用编程语言(General Purpose Language):

可以用来编写任意计算机程序,并且能表达任何的可被计算的逻辑,同时也是图灵完备的。例如,Java、C、Python。

领域专用语言(Domain Specific Language):

能够高效的描述特定领域的世界观和方法论的语言。例如,SQL、HTML & CSS、Regex。

平衡本质:

DSL 通过在表达能力上做妥协以换取在某一领域内的高效表达 (世界级软件开发大师 Martin Fowler 对于DSL的解释)。有限的表达能力就成为了 GPL 和 DSL 之间的一条界限。DSL高效简洁的领域语言,与通用语言相比能极大降级理解和使用难度,同时极大提高开发效率的语言。

DSL需要有特定解析器对其进行构建:

  • 没有计算和执行的概念;
  • 本身不需直接表示计算;
  • 只需声明规则和事实及某些元素之间的层级和关系;

解析器概念

功能:

1. 设计词法、语法、语义:定义 DSL 中的元素是什么样的,元素代表什么意思

2. 实现 Parser,对 DSL 解析,最终通过解释器来执行

核心概念:

1. 抽象语法树(Abstract Syntax Tree,AST):

抽象语法树是源代码结构的一种抽象表示,它以树的形状表示语言的语法结构。

抽象语法树一般可以用来进行代码语法的检查,代码风格的检查,代码的格式化,代码的高亮,代码的错误提示以及代码的自动补全等等。

2. 词法解析器 Lexer:

词法分析是指在计算机科学中,将字符序列转换为单词(Token)的过程。

3. 语法解析器 Parser:

语法解析器通常作为 编译器解释器 出现。它的作用是进行语法检查,并构建由输入单词(Token)组成的数据结构(AST)。

常见解释器:Apache Antlr、SQLParser、Apache Calcite(JavaCC)

Apache Antlr


概念:

它的鼻祖级工具是lex、yacc。 举例,如何将java源码转换成字节码?实现这个需求,需要按照java规范,将源码中的每个词法(如public、class、package)、类名、包名等转换成对应的字节码。那么如何取得这些词、类名、包名、变量名呢? 正则表达式在这里可能就显得力不从心了。因为除了要寻找这些词法外,还需要处理复杂的上下文关系(如变量的作用范围)。这些正是antlr擅长的地方。

谁在使用:Hive、Spark、Oracle、Presto、Elasticsearch

核心组件: 词法Lexer + 语法Parser

1. 词法Lexer:

  • 标识符,即各类编程语言中所说的以下划线、字母开头的字符串
  • 字面量,英文叫Literal,其实就是可以当作值的东西,放在操作符两边。如数字、单引号字符串、双引号字符串、各个进制写法等
  • 字符,单字符(!、~、=、>等)、双字符(>=、<=)等
  • 关键字,如Java中的class、package、import、public等

2. 语法Parser:

  • 例如,变量定义、类定义

词法和语法规则配置放在 .g4 文件里。

Apache Calcite

概念:

是面向 Hadoop 新的查询引擎,它提供了标准的 SQL 语言、多种查询优化和连接各种数据源的能力,除此之外,Calcite 还提供了 OLAP 和 流处理 的查询引擎。

使用Calcite作为SQL解析与处理引擎有:Hive、Drill、Flink、Phoenix、Storm。

历史:

起源于Hive,原名optiq,为 Hive 提供基于成本模型的优化。2014年成为Apache孵化项目,并更名Calcite。建设者是Julian Hyde,曾经是 Oracle 引擎的主要开发者、SQLStream 公司的创始人和主架构师、Pentaho BI 套件中 OLAP 部分的架构师和主要开发者。现在他在 Hortonworks 公司负责 Calcite 项目。

设计目标:

“ one size fits all (一种查询引擎,连接多种前端和后端)”,希望能为不同计算平台和数据源提供统一的查询引擎,并以类似传统数据库的访问方式(SQL 和高级查询优化)来访问Hadoop 上的数据。

设计目标是成为动态的数据管理系统,所以在具有很多特性的同时,也舍弃了比如数据存储、处理数据的算法和元数据仓库。在应用和数据存储及数据处理引擎之间很好地扮演中介的角色。

特性:

1. 支持标准 SQL 语言;

2. 独立于编程语言和数据源,可以支持不同的前端和后端;

3. 支持关系代数、可定制的逻辑规划规则和基于成本模型优化的查询引擎;

4. 支持物化视图(materialized view)的管理(创建、丢弃、持久化和自动识别);

Calcite 的物化视图是从传统的关系型数据库系统(Oracle/DB2/Teradata/SQL server)借鉴而来,传统概念上,一个物化视图包含一个 SQL 查询和这个查询所生成的数据表。

物化视图可以进一步扩展为 DIMMQ(Discardable, In-Memory, Materialized Query)。简单地说,DIMMQ 就是内存中可丢弃的物化视图,它是高级别的缓存。

5. 基于物化视图的 Lattice 和 Tile 机制,以应用于 OLAP 分析;

6. 支持对流数据的查询。

Calcite 对其 SQL 和关系代数进行了扩展以支持流查询。Calcite 的 SQL 语言是标准 SQL 的扩展,而不是类 SQL,这个差别非常重要。

核心组件:

1. 模板引擎FreeMarker

语法模板文件 parserImpls.ftl + 配置文件 conf.fmpp -> .jj 模板文件

2. 语法解析器JavaCC

.jj 模板文件 -> 生成解析器代码文件 .java

在Flink源码工程中的体现:

工程机理:

例如,Flink SQL中的 WATERMARK FOR AS 定义水位线,我们来看看涉及到哪些东西:

1. parserImpls.ftl:

主要完成:

(1) 定义三个成员变量:eventTimeColumnName、pos、watermarkStrategy

(2) 为事件时间属性名eventTimeColumnName赋值

(3) 为字符串位置偏移量pos赋值

(4) 为水位线所属的AST树节点SqlNode赋值watermarkStrategy

这里的赋值是由calcite codegen生成的解析器代码完成的(下节介绍),而SqlWatermark是引入的类,我们看一看这个SqlNode:

这个SqlWatermark本质是对SqlNode的规则定义,继承自SqlCall,UML如下,

所以本质就是一个SqlNode。

但是在哪里引入的SqlWatermark类呢?我们看Parser.tdd

而在这个文件的开始有这个定义:

FlinkSqlParserImpl即为Calcite根据DSL文件描述文件parserImpls.ftl生成的类名的定义。

而parserImpls.ftl和Parser.tdd是如何产生联系的呢?我们看config.fmpp,

至此,我们大致了解Flink是如何在工程角度与Calcite相遇的,更多细节限于笔者能力和时间有限就不过多展开了。下一篇将介绍Calcite在Flink中的解析流程及一些细节。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 章鱼沉思录 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档