Fork me on GitHub

蚂蚁集团金融场景下图表融合分析语言实践

以下文章来源于 https://zhuanlan.zhihu.com/p/637849156

导读 今天和大家分享蚂蚁金融场景下图表融合分析语言实践。

全文围绕下面四点展开:

  1. 图语言及其应用

  2. GeaFlow 图表融合的 DSL

  3. 性能优化

  4. 未来规划

分享嘉宾|彭志伟 蚂蚁集团 技术专家

编辑整理|洪佳胤 北银消费金融

出品社区|DataFun



01/图语言及应用

首先和大家分享下图语言及其应用。

1. 图模型

首先简单地介绍一下图模型。图模型是以图结构来描述实体关系的模型,它用点来表达实体,用边来表达关系。比如在人际关系这个图里,我们每个人就是图里面的点,人与人之间的关系就是它的边。人与人之间可能是好友关系、家庭成员关系或者转账关系,每种类型的关系就对应图里一种类型的边。另外一个是属性图。属性图是图模型里非常重要的一个模型,主要是点、边带属性的图。比如,在人际关系这条边里,有姓名、年龄、职业这些属性;在转账这条边里,有转账金额、转账时间等属性。属性图也是蚂蚁图计算场景研究的一个重要模型。

相比表模型而言,图模型的有以下几个优势。首先, 它有更好的描述能力,可以支持复杂关系建模;第二, 它有更强的表达能力,在复杂关系查询以及复杂图算法的描述方面比表模型更强的;**第三,**它有更好的性能,因为图模型采用图的这种数据结构,在计算上采用以点或边为中心的 Traversal 计算方式,在处理复杂关系查询的时候,相比于表用 Join 的计算方式,图模型有更好的性能。

2. 图查询语言

目前主要的图查询语言非常多,包括 Gremlin、Cypher、GSQL、ISO/GQL、PGQL 等,但这些图查询语言目前还没有一个统一的标准。**图查询语言的主要特点是,它们都是以 Graph Pattern Match 作为核心,**比如在 ISO/GQL 里,可以通过 Match 语句定义一个查询的 pattern;在 Gremlin 里也可以通过 g.V(1).as('a').outE('knows').as('e').inV().as('b') 这种方式来定义同样的查询 pattern。通过 Pattern Match 这种方式可以非常直观地表达复杂的关系。我们可以写一个非常复杂 pattern match 语句。同时,图查询语句里也支持循环、嵌套以及分支选择等高级语言表达,同时还支持图算法的描述能力。

**在 GeaFlow 里采用图语言主要有两个,一个是 Gremlin,另一个是 ISO/GQL。**Gremlin 是 Apache 开源的图查询语言,在业界也有非常多的应用。Gremlin 的写法上偏函数式,所以在写简单图查询上非常直观。ISO/GQL 是 ISO 国际标准委员会制定中的一个图查询标准语言。它主要吸收了一些主流图查询语言的优点,在写法上更接近于 SQL 的语法,所以对数据开发的同学可能会更容易接受。

3. 主要应用场景

图查询语言主要的应用场景包括社交网络、协同推荐、金融风控等。第一个是社交网络, 比如多度关系的查询,可以查二度好友数量、两个好友之间最短路径等。第二个是协同推荐, 比如可以根据用户的兴趣、好友关系来进行同类产品的推荐以及相似度算法的推荐。**第三是金融风控,**金融风控是蚂蚁图查询语言应用中非常典型的一个应用场景,比如做用户行为检测来判断是不是套现行为、发现黑产团伙之类的异常群体等。另外,知识图谱也是图查询语言一个非常重要的应用场景,比如关系挖掘、查找共同根节点、最短路径分析等。当然,图和图语言的应用还有非常多,这里就不一一展开。

4. 应用形态

在蚂蚁的场景下,GeaFlow 的主要应用形态包括三个部分,一是图的离线仿真, 主要是针对大量的历史数据做图特征计算,用以验证模型的正确性,帮助快速上线图特征模型。图特征是基于图模型计算的业务特征,可以帮助我们挖掘多度关系,这对于风控安全等场景具有重要价值。**二是实时图计算,**实时图计算也是 GeaFlow 非常重要的能力,它的计算架构如下:首先会有一份全量图数据和一份实时的数据源,全量数据作为底图存放在图存储中。我们把实时数据源通过窗口切换成很多小的时间分片,每个时间分片的数据会构造一个增量图 ΔG,增量 ΔG 图和全量图一起做图计算,将计算结果输出成表。

另外,在这个计算过程中,也可以将增量部分更新到全量图里。实时图的典型场景主要包括实时风控系统、反欺诈、反套现系统等时效性要求比较高的图计算场景。**GeaFlow 第三个应用形态是图的 OLAP 分析。**图的 OLAP 分析主要是将各种异构数据源的数据实时构图,GeaFlow OLAP 提供分析服务的能力,用户可以通过它做一些图的分析探索,获取多度关系查询等。GeaFlow 提供了一套图表融合的 DSL 来支持以上这三种应用形态。

02 /GeaFlow DSL

1. GeaFlow 介绍

在介绍 GeaFlow DSL 之前,首先介绍一下 GeaFLow。GeaFlow 是蚂蚁自研的实时图计算引擎,在蚂蚁的金融风控、知识图谱等业务场景中广泛使用。GeaFlow 的特点和功能如下:首先, GeaFlow 是图的一个大数据计算引擎。这是它和图数据库的一个显著区别;其次, 它是一个分布式的流图计算引擎,具备流图计算的能力。业界也存在一些图计算引擎,比如 Spark GraphX,但后者主要是偏离线计算;而 GeaFlow 具备实时图计算能力。**另外,**业界在实时图计算领域也有一些开源的产品,例如 GraphBolt,它主要是单机的流图计算引擎,不具备分布式计算能力。以上这些是 GeaFlow 和业界同类产品之间的差异。

另外,GeaFlow 也具备流批一体的能力,它不光具有流图的能力,还具有批量图计算的能力,另外也具备图 OLAP 分析的能力。接下来介绍 GeaFlow 发展历程,大体经过了三个阶段,在 2016 年到 2018 年,在蚂蚁实时计算引擎的基础之上,扩充了图的能力,实现了初代的流图引擎;2018 年到 2020 年,GeaFlow 引擎功能上逐步的完善,实现了流批一体的能力以及图 OLAP 的能力,GeaFlow 成长为一个支持多种计算形态的图计算引擎;2020 年至今,蚂蚁的 GeaFlow 主要朝云原图计算引擎这个方向发展和演进。

2. GeaFlow 架构

从上往下,GeaFlow 的架构中,最上面是 SQL plus,我们在 SQL 的基础上扩展图查询语言的能力,包括 SQL 和 Gremlin 融合、SQL 和 ISO/GQL 融合的能力。GeaFlow Library 就是图的算法库。下面这一层是 GraphView API,也是 GeaFlow 的编程接口,我们围绕着 GraphView 定义了图运算的一套 API。再往下是我们统一的图计算 Runtime 层,包含了 GeaFlow 流批一体的图算子、任务调度以及图的 suffle 等引擎侧的能力。接下去是 Graph State,也就是 GeaFlow 的存储,它采用一种存算分子的架构,可以很好地适应这种云原生的环境。整个引擎的底座是 K8s,GeaFlow 是一个部署在云上的实时图计算引擎。还有一部分是 GeaFlow 的 console,是我们研发一体化的图研发平台,主要提供一个图的 schema 的定义、图作业的创建、管理、运维以及集群资源管理等方面的产品方面的能力。

3. 图表融合 DSL 的意义------业务场景需要

我们之所以去做图表融合 DSL,首先是业务上的场景需要。比如,业务上有异构数据源的构图,即将异构数据源的数据转换成图模型。而异构的数据源,主要包括 Kafka、Hive、HDFS 等,需要对这些数据进行 ETL 清洗,这个过程是表的操作。而我们还需要将表的数据转换成图的数据。这个过程里既有图的操作处理,也有表的操作处理。另外一个是实时图场景。之前介绍了实时图计算的流程,在实时图的场景下,我们需要将实时数据的接收过来,做一个增量构图来触发图计算;同时,图计算的结果也需要回流写入输出表里。这也涉及到表的操作和图的计算。所以,在业务场景上是普遍存在图表融合处理的需求。

4. 图表融合 DSL 的意义------DSL 完备性需要

另外,图表融合也是 DSL 完备性的需要。比如,图的构建本身需要表的处理;同时,图语言处理的结果也需要进一步做表的运算加工;另外,图处理不能脱离表处理单独存在,图表处理是一个整体。右边是图表一体处理的流程图。所以 DSL 需要具备一体化的图表描述的能力。

5. 图表融合 DSL 的设计------构图语言

接下来是图表融合 DSL 的设计。首先是语法层面,这里主要介绍它的构图语句以及图表的查询语句。在构图语句中,首先要定义图(CREAT GRAPH),再通过 SQL 的方式将表里的数据 insert 到图里,可以将数据 insert 到点表里,也可以 insert 到边表里。这样就完成一个构图的操作。而图表的分析语句中,这里介绍两种方式,一是 SQL+ISO/GQL,另一个是 SQL+Gremlin。举一个 SQL+ISO/GQL 的例子:首先通过 With 语句定义了一个请求表,这个请求表数据会去触发下面的 Match 图查询,图查询的结果再返回给 SQL 做一些过滤、聚合等处理,最后写到结果表里。可以看到,这个过程整体上是一个图表一体的处理流程。SQL+Gremlin 类似,我们可以在 SQL 里可以直接 select Gremlin 语句,同时也可将一个子查询作为一个请求表,去触发这个 Gremlin 的执行,最后将结果输出。

6. 图表融合 DSL 的设计------逻辑执行计划

接下来是图表融合的逻辑执行计划,我们在 SQL 关系代数的基础之上,扩展了一些图的运算代数,比如,最上面是 SQL 的一些关系代数,包括 Filter(过滤)、Table Scan(表的扫描)、Project 等;下面我们扩展了图的一些关系运算,包括 Graph Scan(扫描图)、Graph Match(图模式匹配)以及 Graph Modify(将表的数据转化为图的数据)和 Path Modify(修改路径上点或边的属性)等。

这些执行计划主要围绕三种基本结构展开,包括 Graph、Path 和 Table。Table 首先通过 Graph Modify 来构图,得到一个图后,通过 Graph Match 进行图匹配得到路径,Path 再通过 SQL 的关系运算(比如 Project、Aggerate)得到一个表。我们可以看到,这些运算在这三种结构上能够形成一个运算闭环。右侧是一个具体的例子,上面是 SQL+ISO/GQL 的融合语句,先做 Match 路径匹配,然后 return,再通过 SQL select 一些字段,最后写到结果表里。这段语句对应的执行计划是下面这样的:从下往上看,首先用 Graph Scan 做图扫描、读取图的数据;然后执行 Graph Match,做一个图路径匹配;然后是用 Project 做投影运算、筛选字段;最后通过 Table Modify 将它写入结果表里。我们可以看到,这个执行计划既有表的关系运算,也有图的关系运算。图表的运算在逻辑上能够很好地融合在一起。

7. 图表融合 DSL 的设计------物理执行计划

图表融合的一个物理执行计划。前面介绍了图表融合一个逻辑执行计划,基于这个一体的逻辑执行计划,可以生成统一的物理执行计划。我们可以将图表的执行计划生成一个完整的物理执行计划,例如右边这张图。这是 GeaFlow 的物理执行计划,里面包含表的处理算子,例如 Table Scan 读表的数据、Filter 过滤;同时也包含图的运算:图的 Iterator 迭代算子,进行图的 Traversal 运算。基于统一的物理执行计划,我们可以做到统一的资源调度和管理,同时也能做到算子流批一体的执行模式,既可以以流的方式运行,也可以以批的方式运行。

8. 图表融合 DSL 的能力

接下来是图表融合 DSL 能力的介绍。首先,DSL 具备流批一体的执行能力,同一段 DSL 既可以以批的方式跑,也可以以流的方式跑。第二,我们支持 SQL+ISO/GQL 以及 SQL+Gremlin 两种融合的语法;另外,支持标准的 SQL 语法,同时 Gremlin 在 GQL 和 Gremlin 之上我们也做了相应的能力扩展和加强,使其能够支持 LDBCBI 和 Short 等复杂图查询语句;也支持多种的外部数据源和可自定义的扩展,同时也内置丰富的图算法库。最后,用户也可以通过自定义 UDF 的方式去定制一些图算法。基于这种图表融合的 DSL,我们可以有两方面的优势,一是可以用一套介绍解决图表分析的问题,另一个是可以降低用户使用图计算的门槛,用户可以像写 SQL 的类似方式去写图计算的作业。

9. 图表融合 DSL 的应用

图表融合 DSL 典型的应用场景之一,是实时反套现系统。实时反套现系统也是蚂蚁非常典型的一个实时图计算的应用。实时反套现系统主要解决什么问题呢?实际业务中,蚂蚁每天会有大量的交易和转账产生,这些转账、交易里可能会存在一些异常行为,比如套现行为。实时反套现系统主要是利用实时图计算的能力来实时发现这些异常行为,帮助公司止损。

实时反套现的实现主要是有以下几部分:首先,我们有各种数据源,包括交易流、转账流、用户流这些数据,GeaFlow 会将这些数据进行离线构图并写入全量图中;我们通过一个实时的图计算作业将这些实时数据,例如实时交易流数据进行增量构图,再和全量图中的数据结合,触发动态图探索,进行增量的图计算。这样可以算出一些图的特征和指标,比如这个交易是否存在环路等,再将这些指标交给监控和决策平台,决策平台通过策略去判断这个交易是否存在套现行为。

这部分 DSL 的能力主要体现在以下几个方面:一是实时和离线的构图能力;二是图表一体实时图计算的能力,就是既存在表的处理,也存在图的计算;三是性能上支持千亿以及万亿边规模的实时图计算,能够做到秒级的计算延迟。

10. 图表融合 DSL 架构

接下来是图表融合 DSL 架构的介绍。从上往下,最上面是我们的语言层,包括 SQL、ISO/GQL、Gremlin 等;第二层是统一的 Parser,可以将上面的语言转成统一的 AST 语法树;再下一层是逻辑执行计划层,将语法树转成统一的逻辑执行计划,其中包括类型系统去做整个类型的推导,语法校验器来做语法的校验;再往下是图表优化器,主要是将以上生成的执行计划进行优化;最后一层是图表的 Runtime 层,主要是将优化后的执行计划生成底层引擎执行的代码去运行。

03 /DSL 性能优化工作

1. 复杂图查询分布式执行

接下来介绍复杂图查询分布式执行这部分。首先,先介绍一下 DAG 模型。这个模型是目前大数据领域普遍采用的一种分布式执行模型,主要是将计算的逻辑通过一个 DAG 图来表示。比如,在如下 Dag 图里有 source、map、filter、aggregate 和 join 等节点。这些节点会组成一个 Dag 图。每个计算节点可以并行化执行。比如, source 节点可以有多个并发任务去执行。节点之间通过 Shuffle 的方式来进行数据交换,比如,map 节点可以通过 Shuffle 方式将具有相同 Group By key 的数据发给下游 aggregate 节点来做聚合。

这种模型广泛的应用于表处理的分布式化,比如业界的 Spark、Hive 等基本都基于 Dag 模型来做分布式处理。但是,Dag 模型也有局限性,比如它仅支持顺序的执行,只能从前往后按顺序执行,无法支持循环、分支等复杂的计算流程;另外,它也缺乏对子查询的有效支持。

目前在 SQL 里,我们主要通过 Join 的方式来间接表达子查询。但当子查询非常多和复杂的时候,这种表达方式就会变得非常的低效。在图查询的分布式里面所面临的问题,实际上也体现了 DAG 模型的局限性。它普遍存在这种循环、分支等复杂流程,也存在这种大量复杂嵌套的子查询调用。例如,下面这个 Gremlin 语句中,既有 repeat 的循环语句,在 where 中还存在子查询调用。那么我们如何去支持复杂流程语句和嵌套子查询调用的分布式执行,成为我们面临的问题。

2. 复杂查询分布式执行

GeaFlow 基于现有的 DAG 模型做了一些改进,提出来一种可执行的 DAG 模型。首先,我们引入一个数据流跳转的算子,支持数据流跳转执行。它可以支持循环的逻辑,也支持分支跳转的逻辑。比如右边这张图,图里的节点 5 收到上游的 4 给它的数据之后,它可以选择将数据发给 6 去处理,也可以按照一定的条件把数据发回 3 做循环处理。

另外,我们引入了子 DAG 的概念。比如在右边这张图里,有一个主 DAG,同时有两个子 DAG。每个子 DAG 是一个可执行的基本逻辑单元,主 DAG 就相当于高级语言里的 main 函数,那么子 DAG 就相当于高级语言里的子函数。子 DAG 可以被其他 DAG 调用,也可以被嵌套,比如子 DAG 可以再调用另外一个子 DAG。这种模型的优势是在模型上,将 DAG 的计算能力与高级语言对齐,支持循环、跳转、子调用等高级特性。所以它可以支持任意复杂分支循环语句的分布式执行,同时也支持任意复杂的嵌套子查询调用的执行。

基于这样一个模型,我们一方面支持所有的 LDBC BI 类查询语句的分布式并行执行,并且在性能上也取得了比较好的效果;另一方面是我们也支持蚂蚁内部大量复杂图查询的分布式执行。

3. 全链路 Binary 化

下一部分内容介绍一下全链路 Binary 化。GeaFLow 的编程语言是 JAVA,它的好处是生态非常成熟,学习成本也比较低;但是 JAVA 语言的问题也比较明显,一方面是 JAVA 对象模型会导致内存占用非常高。我们都知道,JAVA 是有对象头的。另一方面,JAVA 对象的序列化反序列的成本也非常高,尤其在图的 Shuffle 阶段和读写阶段会存在大量的序列化反序列的开销。基于这个问题,我们做了一个全链路的 Binary 优化,主要是从数据的写入-查询-读写的整个过程都基于二进制的数据结构来表示。使用二进制结构的好处,一是占用更少内存,二是可以做到数据的读写以及 Shuffle 阶段的免序列化。

在技术上,我们主要做了以下几个点:一是 充分利用类型的信息来优化对象的二进制格式,即能够在编译时确定信息都不会放到运行时对象里;二是 针对读写不同的场景设计两套二进制格式,主要是针对读和写两个场景的差异来优化各自的二进制格式;三是针对图场景的复杂类型做大量优化,在图查询场景下,实际上存在大量复杂的类型,例如点、边、路径等。比如复杂对象读阶段做到完全 zero-copy 优化。

另外,我们也支持 Shema Evolution,即支持 Shema 的变更操作,比如说加字段、改类型、减字段的操作;此外,针对 NULL 也做了压缩优化来得到一个更好的优化效果。基于这些优化,我们的业务上也取得一些好结果:在内存上能够降低 50% 左右,在存储大小上能降低 20% 左右,而在整体的查询性能上能提升 5 到 10 倍。

4. 图表融合执行计划优化

如前所述,我们已经做图表融合的一体化执行计划;基于这个执行计划,我们又做了统一的图表优化器。它既可以优化表的执行计划,也可以优化图的执行计划,同时,还能够打破图表优化的界限。比如,我们可以把 SQL 谓词下推给图去做优化;在列裁剪的时候,可以将图表打通。

04 /未来规划

一是 会继续完善图表融合 DSL 的语法能力,能够去支持更多业务场景。同时,也会跟进 ISO/GQL 标准委员会的进展,吸收一些好的语法内容。二是 在性能上,我们会支持 Native 化以及向量化的执行能力,Native 化以及向量化也是目前大数据领域比较热门的方向,例如 Spark、Presto 等都在朝着这个方向发展,我们也希望把这方面的能力运用到图计算中;第三是 完善与大数据生态的整合,包括与现有的数据湖、 Kafka 生态之间更好的整合。**最后,**我们会在 CBO 优化器里支持最优匹配路径的优化。因为在图查询的场景下,路径匹配是一个非常重要的操作,我们希望通过 CBO 优化器能够做出更优的路径匹配顺序。

05 /问答环节

Q1:SQL 和 GQL 的支持都是全语法的支持吗?还是子集?SQL 和 GQL 的融合在语法解析上会有什么冲突的地方?

A1:SQL 是基于 Apache Calcite 实现的标准 SQL 集,GQL 是 ISO/GQL 的子集,同时做了一些语法扩展。在融合上,语法解析目前还没有明显的冲突。

Q2:与 Graph Scope 有什么关系吗?

A2:Graph Scope 是一个阿里集团开源的图计算引擎。GeaFlow 是蚂蚁自研的实时图计算引擎,整体定位更偏实时图处理的能力,同时也具备图分析的能力.

Q3:我们讲到 GeaFlow 是做流批的,那流和批是怎样的定义?延迟和一致性的要求会和普通的图数据库有什么不一样的地方?

A3:在 GeaFlow 里面,我们通过不同的窗口来区分流批,对于批来讲,数据源是有界的,所以是一个 window,我们叫 AllWindow;对于流来讲。数据源是无界的,可以被切分成多个窗口,不同的窗口大小对应不同的时效性和延迟。引擎层面会 window by window 的处理每个窗口的数据。延迟方面,可以根据实际业务需求选择不同的窗口大小,可以做到秒级的计算延迟。图数据库整体偏事务处理,其延迟和一致性要求比较高,GeaFlow 是一个计算引擎,其对延迟和一致性方面,没有事务上的严格要求.

Q4:分支循环是类似 RPC 的调用吗?

A4:GeaFlow DAG 里面的分支循环实际上是对现有 DAG 模型的一个扩展,现有 DAG 模型只支持数据流的顺序执行,无法支持循环等复杂控制流程。我们在 DAG 里面引入数据流跳转的算子来支持数据流的跳转执行。实际上这是一个数据流执行层面的能力扩展,和 RPC 不是一回事.

Q5:在日常实践过程中,金融场景下,流批 Query 和 SNB 的 BI 会有什么差别吗?

A5:这种差别更多的是体现在具体的应用场景上,流图的 Query 一般是点触发查询,通过一批点实时或者离线的方式来触发图查询。BI 类的主要偏分析型语句,一般是全图分析。

今天的分享就到这里,谢谢大家。


本文地址:https://www.6aiq.com/article/1687007441512
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出