一、图查询语言介绍
首先来介绍一下图查询语言的发展历程,大致可以分为三个阶段:图数据库起步、图查询语言起步和图查询语言迭代。
第一个阶段从 2000 年开始,当时还没有图查询语言。Neo4j 希望以 network 的形式,也就是图的形式,去构建数据。当时图数据库的概念还不普遍,当然图的概念可以回溯到上世纪 70 年代甚至更早。在这一时期没有查询语言,因此是使用 Java API 去做,使用 2-3 个接口获取点,然后基于一个点,获取它一度的初边,以这样的形式描述一个图查询。现在看来,无论是 TuGraph 还是 Neo4j,图查询的过程都是遵循最初做图查询的思路,就像 TuGraph 最初也是先有一个 API 的层次,再在上层搭建查询语言。
第二个阶段是图查询语言的起步和发展阶段。最早是 Gremlin,然后是 Neo4j 于 2011 年发布的第一个版本的 Cypher。2012 年 Cypher 成为声明式语言,也就是大家现在习惯使用的通过起点和路径描述查询的方式。2015 年后图查询语言有了迅猛的发展,先是 Oracle 的 PGQL,之后 Neo4j 将 Cypher 开源为 openCypher。2017 年前后 TuGraph 开始加入进来,也是以 openCypher 的标准做了查询语言。2018 年 Cypher 形式化语义的论文发表 Cypher2018。大部分现已成熟的查询语言、图数据库,都是在这十年间如雨后春笋般发展起来的。
第三阶段就是我们现在正在经历的图查询语言迭代阶段。2019 年开始,GQL 成为了国际标准,开始致力于统一不同图查询语言的标准。到了 2023 年,TuGraph 也开始逐步实现 GQL。
上图中罗列了各种查询语言及其厂商。这些查询语言可以分为两大类:声明式(Declarative)和命令式(Imperative)。
声明式图查询语言,包括常见的 Cypher、PGQL、G-CORE,当然 G-CORE 没有具体的实现,但是它的设计是源自于 Cypher 的。这种声明式的语言更加类似于 SQL,更强调查询的目的,而不是查询的过程,比较依赖于查询优化。
命令式的语言,比如 GSQL 和 Gremlin。严格意义上讲,它们是混合式的,因为也会有 select from 嵌入在自己的语句里面。从形式上看,它们更像 Python 这样的语言,因此它们会做的事情更多,这也就意味着用户学习和使用成本会更高。其实与声明式语言的区别在于,具体优化过程是由人来做还是机器来做。比如如果对图了解很多,能直接写图的存储过程,那么使用 GSQL 就会更方便。命令式语言最大的特点就是能写更复杂的图计算能力,例如 page rank。当然,用存储过程去做,再嵌入声明式的语言,也可以实现类似的能力。
再来讲一下前面提到的国际标准 GQL。GQL 在设计上参考了 openCypher、PGQL、GSQL 和 G-CORE,但其核心思想基本上都来自于 openCypher 语言,所以它是一个声明式语言。蚂蚁内部,TuGraph 和 GeaFlow 两个产品都有接入 GQL。长期来看,GQL将会统一声明式查询语言。十年后,就像关系型数据库只有 SQL 语言一样,图数据库声明式语言中也会只剩下 GQL 这一种语言。
现阶段,GQL 还有很多问题,语义方面还没有讨论得非常明确,描述能力也比较有限。比如 FINBENCH,就是看查询语言或者图数据库有哪些瓶颈。上图中展示了 FINBENCH 里面的 complex-read1,金融场景里面查资金流向是比较常见的,比如从一个起点查一个账户,访问出度1-3度的边,就是一个不定跳的过程,如果是资金交易,会有时间要求,比如这笔转账流水是一个时间递增的序列,现在的声明式语言还不能很清晰地描述这种不定跳加时间递增的情况。
考虑到 GQL 将会在图数据库领域实现标准化,蚂蚁现在对 GQL 支持的力度是很大的,除了 TuGraph、GeaFlow 能支持 GQL,其它一些还没有开源的产品基本上也以 GQL 为方向去做接入。
二、查询引擎介绍
接下来介绍 TuGraph 4.0 图查询引擎。
其实在 4.0 版本发布之前,我们 GQL 的语法文件就已经开源了,放在 TuGraph family 里面。4.0 版本实现了 GQL 的能力,当然能力仍比较有限,目前支持 SNB 和 FINBENCH 所有的 SHORT 查询。具体实现可能和开源的语法文件有一些变动,这也是我们认为 GQL 本身不成熟的地方,现在是两个分叉,未来一两年之后,这两个分叉再合并。
近期我们有两项重要的计划,第一是完善 GQL 语法的支持范围,目前仅支持 SNB 和 FINBENCH 的一些最基础的东西,之后会尽快增加比如 DDL 等更多方面的支持。另一件事是架构上的改造,引入一套全新的 GEAX 优化引擎,其目的是希望做一套更通用、对开源社区更友好的优化引擎。
其它方面的计划包括,加入更加完善的 Test Suite 和相应的工具,以及使用查询语言去打榜 SNB 或者 FINBENCH。
提到 SNB 和 FINBENCH,基准测试对于数据库或者查询引擎来说都是非常重要的,但并不是衡量一个查询语言的唯一标准。查询语言的评价维度包括性能、描述能力、健壮性和查询优化等等。
比如查询优化,最简单 Cypher 写法 1 相较于写法 2 更易优化。如果要打一个很好的榜单,一定会用写法 1 的形式,因为写法 2 不一定会优化到,但最终用户使用写法1的体验和效果可能会很差。因此我们对于查询语言的要求会比打榜更高一些。
TuGraph 的具体使用方法,可以参见以下链接:
三、架构及演进计划
下面介绍一下现有的架构,以及后期在架构层面可能会做的改动。
上图是 TuGraph 现在最原始的架构。查询进来,解析到 AST,然后可能有一些验证,到 Planner 出来一个执行计划,根据一些 Schema 信息或者一些统计信息进行优化,之后放入一个执行引擎里面去执行。
目前有两个最大的问题,第一是要支持多个查询语言 Cypher 和 GQL。万幸的是,虽然 GQL 是一个全新的查询语言,但其总体思想来自于 Cypher,体系上可以理解为一样,因此我们可以做到对两种语言的支持。
另一个问题是要支持更多的存储引擎,目前 TuGraph 是一个简单的单机版本,蚂蚁内部已经有分布式的图数据库和一些图计算系统,需要将这些不同的存储引擎都接到我们的查询引擎之上。
关系型数据库和图数据库的层次是比较接近的,因此我们参考了 Calcite 系统。Calcite 是一个完整的查询处理系统,能够提供 DBMS 所需要的许多常用功能,甚至可以接近一个图数据库系统,支持完整的查询语言的优化、解析、验证。我们参考它的架构去做一个类似的处理系统,实现更丰富的算子,在图的优化上能做得更多。
参考这个架构,我们会做 TuGraph 下一个版本的查询引擎的改造,这个改造是在整个执行引擎之上的一层改造。参见上图,右边是 Data Processing System,和 Calcite 的设计类似。左边 GeaX 中有几个核心的模块,第一个就是图语法表示(GST),Quary 解析完之后,这里加了一层抽象,这层抽象能够保证同时支持两个相似的语言,比如 Cypher 和 GQL。同时有一套独立的逻辑算子,能够描述整个查询,有单独的优化器,这里的优化器也支持可插拔的功能。这样整个系统就分为了两部分,前面的查询语言的处理,以及后面的计算和存储。
GeaX 为 TuGraph 提供处理和优化图查询语言的能力,其特点包括,架构与 Calcite 相似,支持查询语言解析、校验、优化。严格意义上 GeaX 不算是一个图计算引擎,因为它把计算的部分全部剥离了,最终产出的是一个逻辑执行计划。另外,GeaX 支持多语言,支持不同的优化器,这些优化器是可插拔的,不同类型的优化器有不同的规则。GeaX 的目标不仅仅是作为一层查询语言接在 TuGraph 上,还能够实现轻松地将 GQL 查询语言接到任何一个图相关的引擎上,比如一个人一个月就能够为 GraphScope 提供 GQL 的能力,这样也为 GQL 成为统一的图声明式查询语言提供帮助。
通过上图的对比可以看出,GeaX 和 Calcite 在框架设计上是比较接近的,当然具体优化器的能力会有不同,这也正是 GeaX 框架的优势之一,可以放不同的优化器在这里。
这个架构是我们未来 3-6 个月要去做的事情,现在已经迈出了第一步,实现了 geax-front-end。目前 parser 这一层已经实现。大概在 3-6 个月左右会有一版迭代,可能会有 GeaX 的出现。我们希望能做一个很简单的 play ground 给用户用,用户能在对 TuGraph 没有很多了解的情况下,尝试去看 GQL 的查询语言生成的逻辑执行计划是什么样的,通过看逻辑执行计划,判断这个查询是不是复杂,是不是可以去增加一些优化规则。