专栏名称: 预流
敲代码的
51好读  ›  专栏  ›  预流

Apache Calcite 论文学习笔记

预流  · 掘金  ·  · 2019-07-17 08:05

正文

阅读 49

Apache Calcite 论文学习笔记

最近在关注大数据处理的技术和开源产品的实现,发现很多项目中都提到了一个叫 Apache Calcite 的东西。同样的东西一两次见不足为奇,可再三被数据处理领域的各个不同时期的产品提到就必须引起注意了。为此也搜了些资料,关于这个东西的介绍 2018 年发表在 SIGMOD 的一篇论文 我觉得是拿来入门最合适了,以下是我关于这篇论文的思考和总结。

是什么

解释 Calcite 是什么,用论文的标题是最合适了—— A Foundational Framework for Optimized Query Processing Over Heterogeneous Data Sources(一个用于优化异构数据源的查询处理的基础框架)。Calcite 提供了标准的 SQL 语言、多种查询优化和连接各种数据源的能力。从功能上看它有很多数据库管理系统的典型功能,比如 SQL 解析、SQL 校验、SQL 查询优化、SQL 生成、数据连接查询等等,但却不包括数据处理、数据存储等 DBMS 的核心功能。从另一方面看,正因为 Calcite 这种与数据处理和存储的无关的设计,才使它成为在多个数据源和数据处理引擎之间进行协调的绝佳选择。

Calcite 之前叫做 optiq,optiq 起初用于 Apache Hive 项目中,为 Hive 提供基于成本模型的优化,即CBO(cost based optimizations)。2014 年 5 月 optiq 独立出来,成为 Apache 社区的孵化项目,2014 年 9 月正式更名为 Calcite。该项目的目标是 one size fits all(一种方案适应所有需求场景),希望能为不同计算平台和数据源提供统一的查询引擎。

Calcite 的主要功能是 SQL 语法解析(parse)和优化(optimazation)。首先它会把 SQL 语句解析成抽象语法树(AST Abstract Syntax Tree),并基于一定规则或成本对 AST 的算法与关系进行优化,最后推给各个数据处理引擎进行执行。

为什么

接下来的问题就是,我们为什么需要这么一个 SQL 语法解析和优化的库呢?

如果你准备自研一个分布式计算产品,肯定少不了类似 SQL 解析、执行的功能,而实现此类功能则存在一定技术门槛,需要设计者对关系代数等领域有比较深的理解。SQL 解析的结果也需要尽量和主流的 ANSI-SQL 一致,这样也能降低公司的推广成本、使用者的学习成本。此外,大数据处理时代的分布式计算场景下,往往一条 SQL 可以解析成多棵语义对等的语法树,但考虑到不同数据结构、底层数据处理的量级、内部的过滤连接等操作的逻辑,这些语法树之间的具体执行效率往往差别很大,SQL 语句不同,底层的执行环境不同,存在的优劣选择也各不相同。

因此,怎么优化这些语法树的执行路径就是一个非常重要的课题。在这两点上,大数据处理中的批量计算、流计算、交互查询等领域多多少少都会存在一些共性问题,当把查询语句背后的关系代数、查询处理和优化等问题封装抽象之后,则有产生一个通用框架的可能。

如果你是一个数据使用者,可能会面临多种异构数据源需要整合(有传统的关系数据库、搜索引擎如 ES、缓存产品如 MongoDB、分布式计算框架如 Spark 等等),此时同样可能面临跨平台的查询语句分发及执行优化等课题。

定位

因此 Apache Calcite 应运而生,论文里把它定位为一个完整的查询处理系统,但 Calcite 的设计是非常灵活,实际项目中一般有两种使用方式:

  1. 把 Calcite 当作 lib 库,嵌入到自己的项目中。

    把 Calcite 的自己产品的系统列表

  2. 实现一个适配器(Adapter),项目通过读取数据源的适配器与 Calcite 集成。

    采用 Calcite 适配器的系统列表

功能聚集

DBMS 五部分

一般来说,我们可以把一个数据库管理系统分为如上五部分, Calcite 在设计之初就确定了只关注和实现图中蓝色三部分,而把灰色的数据管理与数据存储开放给各外部计算、存储引擎来实现。这样做的目的是数据本身的特性导致通常数据管理和数据存储部分即多样(文件、关系数据库、列数据库、分布式存储等等)又复杂,Calcite 放弃了这两部分而专注于上层更通用的模块,使系统的复杂性得到有效控制,聚焦于自己能做、会做、可以做得更深更好的领域。

Calcite 也没有重复去造轮子,有现成东西可用时拿来即用,比如在 SQL 解析这一部分就直接使用了开源的 JavaCC 将 SQL 语句转化为 Java 代码,再转换成一颗抽象语法树供下一阶段使用。又比如为了实现灵活的元数据功能,Calcite 需要支持运行时编译 Java 代码,而默认的 JavaC 太重,需要一个更轻量级的编译器,这里就用了开源的 Janino 。

这种功能聚焦、不重复造轮子、足够简单的产品设计思路使 Calcite 的实现足够简单和稳定。

灵活可插拔架构

Calcite 架构

上图是论文中提到的 Calcite 的架构,Calcite 的优化器使用关系运算符树作为其内部表示,其内部优化引擎主要由三个组件组成:规则、元数据提供者和规划引擎。图中虚线表示 Calcite 与外部的相互作用,从图中可看出这种相互作用的方式有多种。







请到「今天看啥」查看全文