nebulaGraph 选型

Albert 9天前 ⋅ 13 阅读

nebulaGraph 选型

一.why nebulaGraph ?

在图数据库的选型上我们主要考虑了以下 5 点:(A) 项目开源,暂不考虑需付费的图数据库;(B) 分布式架构设计,具备良好的可扩展性;© 毫秒级的多跳查询延迟;(D) 支持千亿量级点边存储;(E) 具备批量从数仓导入数据的能力。

分析 DB-Engines[2] 上排名前 30 的图数据库,剔除不开源的项目,我们将剩余的图数据库分为三类:

  • 第一类:Neo4j[3]、ArangoDB[4]、Virtuoso[5]、TigerGraph[6]、RedisGraph[7]。 此类图数据库只有单机版本开源可用,性能优秀,但不能应对分布式场景中数据的规模增长,即不满足选型要求(B)、(D)。
  • 第二类:JanusGraph[8]、HugeGraph[9]。 此类图数据库在现有存储系统之上新增了通用的图语义解释层,图语义层提供了图遍历的能力,但是受到存储层或者架构限制,不支持完整的计算下推,多跳遍历的性能较差,很难满足 OLTP 场景下对低延时的要求,即不满足选型要求(C)。
  • 第三类:DGraph[10]、NebulaGraph[11]。 此类图数据库根据图数据的特点对数据存储模型、点边分布、执行引擎进行了全新设计,对图的多跳遍历进行了深度优化,基本满足我们的选型要求。

DGraph 是由前 Google 员工 Manish Rai Jain 离职创业后,在 2016 年推出的图数据库产品,底层数据模型是 RDF[12],基于 Go 语言编写,存储引擎基于 BadgerDB[13] 改造,使用 RAFT 保证数据读写的强一致性。

NebulaGraph 是由前 Facebook 员工叶小萌离职创业后,在 2019年 推出的图数据库产品,底层数据模型是属性图,基于 C++ 语言编写,存储引擎基于 RocksDB[14] 改造,使用 RAFT 保证数据读写的强一致性。

这两个项目的创始人都在互联网公司图数据库领域深耕多年,对图数据库的落地痛点有深刻认识,整体的架构设计也有较多相似之处。在图数据库最终的选型上,我们基于 LDBC-SNB 数据集[15]对 NebulaGraph、DGraph、HugeGraph 进行了深度性能测评,测试详情见文章:主流开源分布式图数据库 Benchmark,从测试结果看 NebulaGraph 在数据导入、实时写入及多跳查询方面性能均优于竞品。此外,NebulaGraph 社区活跃,问题响应速度快,所以团队最终选择基于 NebulaGraph 来搭建图数据库平台

二.nebulagraph架构

nebulaGraph架构.png

一个完整的 NebulaGraph 集群包含三类服务,即 Query Service、Storage Service 和 Meta Service。每类服务都有其各自的可执行二进制文件,既可以部署在同一节点上,也可以部署在不同的节点上。下面是NebulaGraph 架构设计(见图 3)的几个核心点[16][17]。

  • Meta Service: 架构图中右侧为 Meta Service 集群,它采用 Leader/Follower 架构。Leader 由集群中所有的 Meta Service 节点选出,然后对外提供服务;Followers 处于待命状态,并从 Leader 复制更新的数据。一旦 Leader 节点 Down 掉,会再选举其中一个 Follower 成为新的 Leader。Meta Service 不仅负责存储和提供图数据的 Meta 信息,如 Schema、数据分片信息等;同时还提供 Job Manager 机制管理长耗时任务,负责指挥数据迁移、Leader 变更、数据 compaction、索引重建等运维操作。
  • 存储计算分离: 在架构图中 Meta Service 的左侧,为 NebulaGraph 的主要服务,NebulaGraph 采用存储与计算分离的架构,虚线以上为计算,以下为存储。存储计算分离有诸多优势,最直接的优势就是,计算层和存储层可以根据各自的情况弹性扩容、缩容。存储计算分离还带来了另一个优势:使水平扩展成为可能。此外,存储计算分离使得 Storage Service 可以为多种类型的计算层或者计算引擎提供服务。当前 Query Service 是一个高优先级的 OLTP 计算层,而各种 OLAP 迭代计算框架会是另外一个计算层。
  • 无状态计算层: 每个计算节点都运行着一个无状态的查询计算引擎,而节点彼此间无任何通信关系。计算节点仅从 Meta Service 读取 Meta 信息以及和 Storage Service 进行交互。这样设计使得计算层集群更容易使用 K8s 管理或部署在云上。每个查询计算引擎都能接收客户端的请求,解析查询语句,生成抽象语法树(AST)并将 AST 传递给执行计划器和优化器,最后再交由执行器执行。
  • Shared-nothing 分布式存储层: Storage Service 采用 Shared-nothing 的分布式架构设计,共有三层,最底层是 Store Engine,它是一个单机版 Local Store Engine,提供了对本地数据的get/put/scan/delete 操作,该层定义了数据操作接口,用户可以根据自己的需求定制开发相关 Local Store Plugin。目前,NebulaGraph 提供了基于 RocksDB 实现的 Store Engine。在 Local Store Engine 之上是 Consensus 层,实现了 Multi Group Raft,每一个 Partition 都对应了一组 Raft Group。在 Consensus 层上面是 Storage interfaces,这一层定义了一系列和图相关的 API。 这些 API 请求会在这一层被翻译成一组针对相应 Partition 的 KV 操作。正是这一层的存在,使得存储服务变成了真正的图存储。否则,Storage Service 只是一个 KV 存储罢了。而 NebulaGraph 没把 KV 作为一个服务单独提出,最主要的原因便是图查询过程中会涉及到大量计算,这些计算往往需要使用图的 Schema,而 KV 层没有数据 Schema 概念,这样设计比较容易实现计算下推,是 NebulaGraph 查询性能优越的主要原因。

NebulaGraph 基于 C++ 实现,架构设计支持存储千亿顶点、万亿边,并提供毫秒级别的查询延时。我们在 3 台 48U192G 物理机搭建的集群上灌入 10 亿美食图谱数据对 NebulaGraph 的功能进行了验证。

  • 一跳查询 TP99 延时在 5ms 内,两跳查询 TP99 延时在 20ms 内,一般的多跳查询 TP99 延时在百毫秒内。
  • 集群在线写入速率约为20万 Records/s。
  • 支持通过 Spark 任务离线生成 RocksDB 底层 SST File,直接将数据文件载入到集群中,即类似 HBase BulkLoad 能力。
  • 提供了类 SQL 查询语言,对于新增的业务需求,只需构造 NebulaGraph SQL 语句,易于理解且能满足各类复杂查询要求。
  • 提供联合索引、GEO 索引,可通过实体属性或者关系属性查询实体、关系,或者查询在某个经纬度附近 N 米内的实体。
  • 一个 NebulaGraph 集群中可以创建多个 Space (概念类似 MySQL 的DataBase),并且不同 Space 中的数据在物理上是隔离的。

全部评论: 0

    我有话说: