架构
ArcGraph 系统架构如下图所示。
-
存、算、分析一体化设计,采用 Graph HTAP 理念,实现在线查询与图计算分析的融合。
-
单机分布式一体化内核架构设计,既可以敏捷部署,又具备强大的性能和横向扩展能力。
-
实现计算与存储的分离,并遵循“Log as Database”的设计理念,解耦计算和存储。
ArcGraph 的 TP 系统可以分为三层
1. 查询引擎(Query Engine)
查询引擎是 ArcGraph 的大脑,它是无状态的 Cypher Query Compiler 引擎。该查询引擎通过采用 Rust 的 Logos 库和 Nom 库来解析 Cypher 语言并生成 AST。随后,通过 Planner 进行转换,利用自研的具备自上向下和自下向上优化框架(借鉴 Cascade 框架的思想),同时结合点和边统计信息以及历史 Plan 信息,通过 RBO、CBO 和 HBO 的多轮 Plan 优化,生成高效的执行计划。
2. 计 算引擎(Computing Engine)
高性能的计算引擎是 ArcGraph 的发动机,采用了 MPP 的架构;该计算引擎承担多项重要任务,包括执行计划的 DAG 切割、 DAG 在分布式 computing 节点间的分发,以及执行计划的启动、暂停、恢复和删除等生命周期管理。最后,计算引擎会暂时缓存计算结果,通过 gRPC 按批发送给客户端。
由于系统采用存、算分离的分布式架构, ArcGraph 的计算引擎采用中心化的 TSO 分配策略以及分布式的 MVCC 能力,以确保分布式事务的隔离性和一致性。同时,它还采用了 multi-raft 协议以确保 WAL log 在多个计算节点的一致性,从而天然的具备了分布式节点之间的 HA 功能。
图数据(点和边)通过灵活的分区策略存储在不同 Partition 中,这些 Partition 可由分布式计算节点池中的不同计算节点提供服务。通过调整分区策略,可以达到优化分布式执行的效果,例如将相关性的点和边数据由同一个计算节点提供服务,从而降低图查询经典多跳时的分布式通讯成本。
3. 存储引擎(Storage Engine)
存储引擎采用 share-nothing 的架构,提供 ArcGraph 的持久层服务。存储层采用多级存储系统,首先是提供高性能数据访问的内存引擎,提供图拓扑信息、MVCC、脏页管理;然后是本地 SSD 固态存储,提供持久化 WAL 日志服务,并借助 Raft 协议来保证节点间的分布式一致性;最后是提供异步写入的远端存储,根据业务系统需要,可以灵活对接单机 RocksDB,分布式 TiKV 或云对象存储(OSS)。
运行模式
ArcGraph 提供了单机版、敏捷版两种运行模式,适用于不同的应用场景。
-
单机版
单机版允许 ArcGraph 在一台机器上快速部署,以便用户可以快速地开始使用。单机版通常适用于个人开发测试,不能保证高可用,因此不建议在生产环境使用。 -
敏捷版
敏捷版通过引入 Raft 技术,允许三个节点之间的数据复制和故障转移,以确保数据的可靠性和系统的可用性,数据三副本存储。敏捷版的性能、容量和稳定性等各方面相对均衡,推荐使用。在存储架构上,敏捷版又分为本地存储和分布式 K/V 存储两种。- 本地存储:数据保存在本机数据盘,性能更优,但容量受限于所在主机的存储空间。
- 分布式K/V存储:数据保存在分布式 Key/Value 集群中,适用于对数据容量有极高扩展性的场景。
数据分区 与 分布式并行查询
数据分区是指将数据集分成若干个较小的子集或分区,以便在分布式系统中进行分布式处理和存储。这种策略可以提高数据处理的效率和灵活性,同时也可以减轻单个节点的处理负担。
架构优势:
-
灵活分区策略
基于哈希的分区策略 Hash(vertex_type), Hash(vertex_id) ...,系统通过使用点类型(Vertex_Type)和点 ID(Vertex_id)等属性作为输入,将其通过哈希函数映射到特定的分区。这种策略可以使 得相同类型或 ID 的顶点在同一个分区中,从而方便针对特定类型的数据进行查询和处理。同时,使用哈希函数可以实现负载均衡,使得每个分区包含大致相同的数据量。 -
分布式存储
基于分区策略达到点/边/索引数据的分布存储效果,通过将数据分区并存储在不同的服务器节点上,可以并行处理和查询各个分区的数据。索引数据可以跨多个分区分布,以提高查询效率。 -
点/边分区一致性
边的分区采用起始点分区一致,加速多跳查询性能,对于边数据,建议按照起始点所在的分区进行划分。这样可以使得同一跳的边的数据在相同的分区中,从而加速多跳查询。 -
基于 Vertex_id 计算点的 location 信息
通过顶点 ID 计算获取点的 location 信息。该架构可以通过一种映射关系或者计算规则,将顶点 ID 映射到具体的地理位置。
ArcGraph 是一个实现分布式查询的图数据库,计算层采用 MPP 分布式架构,每个计算节点采用基于 Push 模式的向量化执行引擎,实现原理大致如下:
(1)执行计划切割——基于 QueryEngine 优化后的物理执行计划,执行引擎先结合算子的属性(例如是否是 pipeline breaker,如 Hash Join 算子),完成对执行计划进行切割,最终生成 DAG 图,基于 DAG 间的依赖关系,对其中的每个子 DAG 进行分布式并行调度执行。
(2)计划分发——根据执行计划中涉及数据 partition 分布信息,把执行计划分发到所涉及的 partition leader 节点。
(3)分布式调度执行——由 coordinator 节点发起 pipeline ,并在计算节点 server 上 分布式行执行;每个计算节点上的计算引擎采用 push 模型,并结合 Batch 方式进行向量化执行,同时算子内部利用协程进行计算加速(例如并行执行多节点的 Expand),高效完成执行计划的分布式并行执行计算。
在计算过程中,如果有些算子产生大量中间结果(如 aggregate 算子),计算引擎具备“Flush to Disk”的功能,可以物化部分结果到外存,从而避免 OOM 的问题。在有些场景中,如果计算引擎生成结果的速度快于 Client 拉取数据的速度,引擎会自动暂停 Pipeline 的执行,等待 Client 消费一定量 ResultCache 中数据后再恢复执行。针对图查询中典型多跳场景,根据节点的亲和性,对于需要到远端机器执行下一跳的节点集合,可以根据不同机器目的地进行缓存,并按批发送到远端机器。这些节点数据发送到对端机器后,会启动新的子 pipeline 进行并行处理,然后根据 Plan 进行后续处理执行。
分布式存储
ArcGraph 存储层基于数据温度实现了“热、温、冷”的三级存储结构:
- 首先,提升 ArcGraph 性能的高效内存引擎,包括常驻内存的图拓扑信息,基于 LRU 的点/边属性 Cache,以及支持 DML 功能的 MVCC,脏页管理和 index buffer 管理。
- 下面一层是基于 Log 即 Database 思想的高效本地存储,用来存放 L1 delta,也就是 WAL 日志,并通过 multi-raft 实现节点间的日志同步达到高可用功能。
- 第三层是传统的持久层,为了方便不同场景的灵活部署,系统采用了多种存储方式:快捷部署的单机 RocksDB 部署,大数据量场景的分布式 K/V 部署,以及性价比友好的 S3/OSS 存储。
我们以 K/V 存储引擎为例,介绍下 ArcGraph 存储功能接口。每个存储节点都有一个 K/V 存储引擎作为持久性存储,从上到下提供三个功能:
- 最上层是计算层提供统一的图查询接口,比如点/边的查询和写入接口。当接到计算层的 Get()或 Put()请求后,首先根据点和边的 Key 在分布式存储中的 NameNode 上查询对应分区拓扑的 Leader 节点信息,然后把请求路由到对应的 KV 节点进行处理。
- 分布式 K/V 存储中间采用 Raft 协议来实现分布式一致性和高可用性。当系统负载发生变化或者存储系统中的节点或者网络出现故障时,分区 Leader 可以人为或基于 Raft 协议自动进行切换。
- K/V 存储引擎用于实现图点/边数据的持久性;为了节省存储空间,会根据系统配置,对数据进行不同程度的压缩存储。
Semi-Stateful 与 Log as Database
随着数据库的存算分离,传统数据库的业务 IO 瓶颈已经转化为计算层和存储层之间的 IO 瓶颈,在这种情况下,底层存储节点和网络时延对于响应时间有很大的影响,事务操作的性能也会很大程度上受到影响,尤其是分布式提交等复杂操作。因此,ArcGraph 采用了 Semi-Stateful 架构,继承了“日志即数据”的思想,并在计算层增加本地高性能 SSD 日志 Store,用以对 DML 的 WAL 日志进行存储,并定期对 WAL 日志进行 CheckPoint,并把 Checkponit 数据写入底层存储引擎。这带来 了如下优点:
- 在 DML 操作中,只需要记录 WAL 日志,从而显著减少了网络占用。
- 将复杂的 DML 操作由数据和日志的同步操作转变为连续的异步操作。
- 引入了一个分布式的、基于 Raft 协议同步的 WAL 日志服务,降低了网络层或数据存储层问题对数据库的影响。
ArcGraph 可采用灵活的分区策略,例如基于点的 ID 或点的 Type 进行 Hash,并采用边的分区跟随起始点的分区策略。通过这种方式,可以将图的点和边数据分为不同的 tablet 分区,每个分区都有多个 WAL 日志的副本,并使用 multi-raft 共识算法来实现 WAL 日志的分布式一致性。在同一个 Raft 组内,节点可以担任不同的角色,包括 Leader、Follower 和 Learner。
- Group Leader:负责接收分区 DML 操作所生成的 WAL 日志写入请求,并在 Raft 组内完成日志的同步及一致性确认, 最后确保成功写入本地的日志 Store。
- 其它 Group Follower 节点(一般是其它 TP 计算节点):完成对 Raft Leader 新的日志进行同步确认,并在心跳超时后发起 Leader 选举。
- Group Learner 节点(通常是 AP 计算节点):对最新的 WAL 日志进行同步,获取最新的 Delta 数据,并将其与从底层存储引擎获取的 Snapshot 数据进行合并,合并后的数据用来完成用户特地场景的 AP 计算(图计算)任务。
图 HTAP
ArcGraph 具备强大的图 HTAP(Hybrid Transactional and Analytical Processing)计算能力,专为低延迟、高并发和复杂的事实计算设计。同时支持 T+1 场景。TP (Transaction Processing)引擎和 AP (Analytical Processing)引擎共享 Cypher Query 前端(Parser,Validator,Planner,Optimizer),根据生成的执行计划,TP 场景的由 TP 引擎分布式并发执行,针对执行计划中的图算法类 AP 算子(比如 SSSP,PageRank),则由 AP 引擎负责进行处理,AP 引擎首先从 TP 引擎获得查询子图,然后进行分布式图计算。此外 AP 引擎也支持从数据库外部加载数据,例如 Hadoop 或者对象存储系统,由此支持了图 HTAP 处理。同时 AP 计算节点实现了 Serverless 能力,可以根据用户请求负载差异,动态扩缩容。
Serverless OLAP
多模态能力
ArcGraph 将向量、JSON 和图进行了深度融合。在图的 Schema 中,通过为属性字段提供 JSON 类型和向量类型的字段支持,实现了图结构的半结构化和向量能力。 以电影知识图谱为例:影片与制作人作为顶点,形成图拓扑关系,每部电影都有其独特的 ID 和其他信息(如标题、年份等),这些信息我们通过使用 JSON 进行表示。此外,我们将电影的内容或简介文本描述进行向量化处理,并将这些向量数据作为电影顶点的属性字段存储在图数据中。 针对向量字段的索引部分,通过 HNSW 索引来加速向量数据的检索。这种索引与图数据的处理结构非常相似,因为它也采用了类似多层图的数据结构。并且使用 HNSW 索引的优点是其检索效率高且召回率较高。为了进一步实现图与向量数据的整合处理,我们在系统中加入了以下三个特性:
- 使用 SIMD 进行距离计算加速,与传统方式相比,我们的方法可以提高 4 倍的性能。
- 支持属性过滤的向量检索功能,同类系统只能进行纯向量检索,而不能进行其他字段(标量)的联合检索。
- 通过原有图技术沉淀,向量数据模型上也实现了完整的 CRUD 和 ACID 功能。
同时 ArcGraph 采用了“One Query”的设计哲学,意在为用户提供一个统一的查询接口。这不仅仅体现在数据模型的统一,更进一步在于查询语言的统一。通过一条查询语句,用户可以同时检索向量数据、JSON 数据和图数据。
ArcGraph 图数据库生态
主要包括产品的客户端、图智能 Analytic 平台、图开发 Studio 平台、Infra 服务及通用服务等方面。ArcGraph 合理的生态布局能够确保产品的稳定性、可扩展性和易用性。
总结
ArcGraph 是一款云原生架构、存查分析一体化(图 HTAP)的分布式多模态图数据库,采用 Multi-Raft 协议来满足系统的分布式一致性和高可用性;同时支持存储节点和计算节点的无缝扩缩容,支持分布式事务和分布式查询功能;通过采用原图内存引擎,支持高性能图查询和 Serverless 图计算;并且通过图、JSON 和向量(Vector) 的深度融合,实现了 ArcGraph 的多模态能力。