共计 9867 个字符,预计需要花费 25 分钟才能阅读完成。
图数据结构,可能更好地表征事实世界。美团业务绝对较简单,存在比拟多的图数据存储及多跳查问需要,亟需一种组件来对千亿量级图数据进行治理,海量图数据的高效存储和查问是图数据库钻研的外围课题。本文介绍了美团在图数据库选型及平台建设方面的一些工作。
1 前言
图数据结构,可能很天然地表征事实世界。比方用户、门店、骑手这些实体能够用图中的点来示意,用户到门店的消费行为、骑手给用户的送餐行为能够用图中的边来示意。应用图的形式对场景建模,便于形容简单关系。在美团,也有比拟多的图数据存储及多跳查问需要,概括起来次要包含以下 4 个方面:
- 图谱开掘: 美团有美食图谱、商品图谱、游览图谱、用户全景图谱在内的近 10 个畛域常识图谱,数据量级大略在千亿级别。在迭代、开掘数据的过程中,须要一种组件对这些图谱数据进行对立的治理。
- 平安风控: 业务部门有内容风控的需要,心愿在商户、用户、评论中通过多跳查问来辨认虚伪评估;在领取时进行金融风控的验证,实时多跳查问危险点。
- 链路剖析: 包含代码剖析、服务治理、数据血统治理,比方公司数据平台上有很多 ETL Job,Job 和 Job 之间存在强弱依赖关系,这些强弱依赖关系造成了一张图,在进行 ETL Job 的优化或者故障解决时,须要对这个图进行实时查问剖析。
- 组织架构: 公司组织架构的治理,实线汇报链、虚线汇报链、虚构组织的治理,以及商家连锁门店的治理。比方,保护一个商家在不同区域都有哪些门店,可能进行多层关系查找或者逆向关系搜寻。
总体来说,美团须要一种组件来治理千亿级别的图数据,解决图数据存储以及多跳查问问题。海量图数据的高效存储和查问是图数据库钻研的外围课题,如何在大规模分布式场景中进行工程落地是咱们面临的痛点问题。传统的关系型数据库、NoSQL 数据库能够用来存储图数据,然而不能很好解决图上多跳查问这一高频的操作。
Neo4j 公司在社交场景(见图 1)里做了传统关系型数据库 MySQL 跟图数据库 Neo4j 的查问性能比照 [1],在一个蕴含 100 万人、每人约有 50 个敌人的社交网络里找最大深度为 5 的敌人的敌人,试验结果表明多跳查问中图数据库劣势显著(见图 2)。然而选取或者自主研发一款高吞吐、低查问延时、能存储海量数据且易用的图数据库十分艰难。上面将介绍美团在图数据库选型及平台建设方面的一些工作。
2 图数据库选型
在图数据库的选型上咱们次要思考了以下 5 点:(A) 我的项目开源,暂不思考需付费的图数据库;(B) 分布式架构设计,具备良好的可扩展性;(C) 毫秒级的多跳查问提早;(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 来搭建图数据库平台。
3 NebulaGraph 架构
一个残缺的 NebulaGraph 集群蕴含三类服务,即 Query Service、Storage Service 和 Meta Service。每类服务都有其各自的可执行二进制文件,既能够部署在同一节点上,也能够部署在不同的节点上。上面是 NebulaGraph 架构设计(见图 3)的几个外围点 16。
- 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 中的数据在物理上是隔离的。
4 图数据库平台建设
为了对立治理图数据,缩小工程同学在图数据库集群上的运维压力,咱们基于开源分布式图数据库 NebulaGraph,搭建了一套一站式图数据库自助治理平台(见图 4),该平台蕴含以下 4 层:
- 数据应用层。 业务方能够在业务服务中引入图谱 SDK,实时地对图数据进行增删改查。
数据存储层。 反对两种图数据库集群的部署。
- 第一种部署形式是 CP 计划,即 Consistency & Partition tolerance。单集群部署,集群中机器数量大于等于正本的数量,正本数量大于等于 3。只有集群中有大于正本数一半的机器存活,整个集群就能够对外失常提供服务。CP 计划保障了数据读写的强一致性,但这种部署形式下集群可用性不高。
- 第二种部署形式是 AP 计划,即 Availability & Partition tolerance。在一个利用中部署多个图数据库集群,每个集群数据正本数为 1,多集群之间进行互备。这种部署形式的益处在于整个利用对外的可用性高,但数据读写的一致性要差些。
- 数据生产层。 图数据次要有两种起源,第一种是业务方把数仓中数据通过 ETL Job 转成点和边的 Hive 表,而后离线导入到图数据库中;第二种是业务线上实时产生的数据、或者通过 Spark/Flink 等流式解决产生的近线数据,调用在线批量写接口实时灌到图数据库中。
- 撑持平台。 提供了 Schema 治理、权限治理、数据质检、数据增删改查、集群扩缩容、图谱画像、图数据导出、监控报警、图可视化、集群包治理等性能。
与业界计划相比,团队主导设计的图数据库平台除了反对存储千亿顶点、万亿边,具备毫秒级别查问能力外,还提供了如下四项能力:利用可用性 SLA 达 99.99%;反对每小时百亿量级数据导入;实时写入数据时保障多集群数据最终一致性;易用的图谱可视化能力。上面将介绍具体的设计思路。
4.1 高可用模块设计
首先介绍单利用多集群高可用模块的设计(AP 计划)。为什么有 AP 计划的设计呢?因为接入图数据库平台的业务方比拟在意的指标是集群可用性。在线服务对集群的可用性要求十分高,最根底的要求是集群可用性能达到 4 个 9,即一年里集群的不可用工夫要小于一个小时。对于在线服务来说,服务或者集群的可用性是整个业务的生命线,如果这点保障不了,即便集群提供的能力再多再丰盛,那么业务方也不会思考应用,可用性是业务选型的根底。
另外,公司要求中间件要有跨区域容灾能力,即要具备在多个地区部署多集群的能力。咱们剖析了平台接入方的业务需要,大概 80% 的场景是 T+1 全量导入数据、线上只读。在这种场景下,对图数据的读写强一致性要求并不高,因而咱们设计了单利用多集群这种部署计划。
AP 计划部署形式能够参考图 5,一个业务方在图数据库平台上创立了 1 个利用并部署了 4 个集群,其中北京 2 个、上海 2 个,平时这 4 个集群同时对外提供服务。如果当初北京集群 1 挂了,那么北京集群 2 能够提供服务。如果说真那么不巧,北京集群都挂了,或者北京侧对外的网络不可用,那么上海的集群也能够提供服务。在这种部署形式下,平台会尽可能地通过一些形式来保障整个利用的可用性。而后每个集群外部尽量部署同机房的机器,因为图数据库集群外部 RPC 十分多,如果有跨机房或者跨区域的频繁调用,整个集群对外的性能会比拟低。
高可用模块次要蕴含上面 4 个局部,如上图 6 所示:
第一局部是右侧的图数据库 Agent,它是部署在图数据库集群的一个过程,用来收集机器和图数据库三个外围模块的信息,并上报到图数据库平台。Agent 可能接管图数据库平台的命令并对图数据库进行操作。
第二局部是图数据库平台,它次要是对集群进行治理,并同步图数据库集群的状态到配置核心。
第三局部是图数据库 SDK,次要负责管理连贯到图数据库集群的连贯。如果业务方发送了某个查问申请,SDK 会进行集群的路由和负载平衡,抉择出一条高质量的连贯来发送申请。此外,SDK 还会解决图数据库集群中问题机器的主动降级以及复原,并且反对平滑切换集群的数据版本。
第四局部是配置核心,相似 ZooKeeper,存储集群的以后状态。
4.2 每小时百亿量级数据导入模块设计
第二个模块是每小时百亿量级数据导入模块,平台在 2019 年底 - 2020 年初全量导入数据的形式是调用 NebulaGraph 对外提供的批量数据导入接口,这种形式的数据写入速率大略是每小时 10 亿级别,导入百亿数据大略要消耗 10 个小时,耗时较长。此外,在以几十万每秒的速度导数据的过程中,会长期占用机器的 CPU、IO 资源,一方面会对机器造成损耗,另一方面数据导入过程中集群对外提供的读性能会变弱。
为了解决下面两个问题,平台进行了如下优化:在 Spark 集群中间接生成图数据库底层文件 SST File,再借助 RocksDB 的 Bulkload 性能间接 ingest 文件到图数据库。
数据导入的外围流程能够参考图 7,当用户执行导数据操作后,图数据库平台会向公司的 Spark 集群提交一个 Spark 工作,在 Spark 工作中会生成图数据库里相干的点、边以及点索引、边索引相干的 SST 文件,并上传到美团的 S3 云存储上。文件生成后,图数据库平台会告诉利用中多个集群去下载这些存储文件,之后实现 ingest 跟 compact 操作,最初实现数据版本的切换。
为兼顾各个业务方的不同需要,平台对立了利用导入、集群导入、离线导入、在线导入,以及全量导入、增量导入这些场景,而后细分成上面九个阶段,从流程上保障在导数据过程中利用整体的可用性:SST File 生成、SST File 下载、ingest、compact、数据校验、增量回溯、数据版本切换、集群重启、数据预热。
4.3 实时写入多集群数据同步模块设计
第三个模块是实时写入多集群数据同步模块,平台约有 15% 的需要场景是在实时读取数据时,还要把新产生的业务数据实时写入集群,并且对数据的读写强一致性要求不高。就是说,业务方写到图数据库里的数据,不须要立马能读到。针对上述场景,业务方在应用单利用多集群这种部署计划时,多集群里的数据须要保障最终一致性。针对这一需要,咱们做了以下设计。
第一局部是引入 Kafka 组件,业务方在服务中通过 SDK 对图数据库进行写操作时,SDK 并不间接写图数据库,而是把写操作写到 Kafka 队列里,之后由该利用下的多个集群异步生产这个 Kafka 队列。
第二局部是集群在利用级别可配置生产并发度,来控制数据写入集群的速度。具体流程如下:
- SDK 对用户写操作语句做语法解析,将其中点边的批量操作拆解成单个点边操作,即对写语句做一次改写。
- Agent 生产 Kafka 时确保每个点及其出边相干操作在单个线程里程序执行(见图 8),保障这点就能保障各个集群执行完写操作后最终的后果是统一的。
- 并发扩大:通过扭转 Kafka 分片数、Agent 中生产 Kafka 线程数来调整 Kafka 中操作的生产速度。如果将来图数据库反对事务的话,下面的配置须要调整成单分片单线程生产,有必要对设计方案再做优化调整。
第三局部是在实时写入数据过程中,平台能够同步生成一个全量数据版本,并做平滑切换(见图 9),确保数据的不重、不漏、不提早。
4.4 图可视化模块设计
第四个模块是图可视化模块(见图 10),次要是用于解决子图摸索问题。当用户在图数据库平台通过可视化组件查看图数据时,能尽量通过失当的交互设计来防止因为节点过多而引发爆屏。次要包含以下几个性能:
- 通过 ID 或者索引查找顶点。
- 能查看顶点和边的卡片(卡片中展现点边属性和属性值),能够单选、多选、框选以及按类型抉择顶点。
- 图摸索,当用户点击某个顶点时,零碎会展现它的一跳街坊信息,包含该顶点有哪些出边?通过这个边它能关联到几个点?该顶点的入边又是什么状况?通过这种一跳信息的展现,用户在平台上摸索子图的时候,可疾速理解到周边的街坊信息,更快地进行子图摸索。在摸索过程中,平台也反对通过属性对边进行过滤。
- 图编辑能力,让平台用户在不相熟 NebulaGraph 语法的状况下也能增删改点边数据,对线上数据进行长期干涉。
5 业务实际
5.1 智能助理
该我的项目数据是基于美团商户数据、用户评论构建的餐饮娱乐常识图谱,笼罩美食、酒店、游览等畛域,蕴含 13 类实体和 22 类关系。目前,点边数量大略在百亿级别,数据 T+1 全量更新,次要用于解决搜寻或者智能助理里 KBQA(全称:Knowledge Based Question Answer)类问题。外围解决流程是通过 NLP 算法辨认关系和实体后结构出 NebulaGraph SQL 语句,再到图数据库获取数据。
典型的利用场景包含商场找店,比方,某个用户想晓得望京新荟城这个商场有没有海底捞,零碎能够疾速查出后果通知用户;另一个场景是标签找店,用户想晓得望京 SOHO 左近有没有适宜情侣约会的餐厅,或者能够多加几个场景标签,零碎都能够帮忙查找进去。
5.2 搜寻召回
该我的项目数据是基于医美商家信息构建的医美常识图谱,蕴含 9 类实体和 13 类关系,点边数量在百万级别,同样也是 T+1 全量更新,次要用于大搜底层实时召回,返回与 Query 相干的商户、产品或医生信息,解决医美类搜索词少后果、无后果问题。比方,某个用户搜“啤酒肚”这种症状、或者“润百颜”这类品牌,零碎能够召回相干的医美门店。
5.3 图谱举荐理由
该我的项目数据来自用户的画像信息、商户的特色信息、用户半年内珍藏 / 购买行为,数据量级是 10 亿级别,T+1 全量更新。当初美团 App 和点评 App 上默认的商户举荐列表是由深度学习模型生成的,但模型并不会给出生成这个列表的理由,短少可解释性。
而在图谱里用户跟商户之间人造存在多条连通门路,我的项目思考选出一条适合门路来生成举荐理由,在 App 界面上展现给用户举荐某家店的起因。该我的项目基于用户的协同过滤算法来生成举荐理由,在他乡、消费水平、偏好类目、偏好菜系等多个组合维度中找出多条门路,而后给这些门路打分,选出一条分值较高的门路,之后依照特定 Pattern 产出举荐理由。通过上述形式,就能够取得“在北京喜爱北京菜的山东老乡都说这家店很赞”,或者“广州老乡都中意他家的正宗北京炸酱面”这类理由。
5.4 代码依赖剖析
该我的项目把代码库中代码依赖关系写入到图数据库。代码库中存在很多服务代码,这些服务会包含对外提供的接口,这些接口的实现依赖于该服务中某些类的成员函数,这些类的成员函数又依赖了本类的成员变量、成员函数或者其它类的成员函数,那么它们之间的依赖关系就造成了一张图,能够把这个图写到图数据库里做代码依赖剖析。
典型利用场景是精准测试:当开发同学实现需要并向公司的代码仓库提交了 PR 后,能够把更改实时地写到图数据库中。这样的话,开发同学就能查到他所写的代码影响了哪些内部接口,并且借助图可视化组件查看调用门路。如果开发同学原本是要改接口 A 的行为,改了很多代码,然而他可能并不知道他改的代码也会影响到对外接口 B、C、D,这时候就能够用代码依赖剖析来做个 Check,减少测试的齐备性。
6 总结与瞻望
目前,图数据库平台根本具备了对图数据的一站式自助治理性能。如果某个业务方要应用这种图数据库能力,那么业务方能够在平台上自助地创立图数据库集群、创立图的 Schema、导入图数据、配置导入数据的执行打算、引入平台提供的 SDK 对数据进行操作等等。平台侧次要负责各业务方图数据库集群的稳定性。目前,美团有三四十个业务曾经在平台上落地,根本满足了各个业务方的需要。
将来布局次要有两个方向,第一,依据业务场景优化图数据库内核,晋升平台稳定性,开发的通用 Feature 继续反哺 NebulaGraph 社区。第二,开掘更多的图数据价值。当初平台仅反对图数据存储及多跳查问这种根本能力,后续将基于 NebulaGraph 去摸索图学习、图计算的能力,为平台用户提供更多开掘图数据价值的性能。
7 作者信息
登昌、梁帅、高辰、杨鑫、尊远、王超等,均为美团搜寻与 NLP 部工程师。
8 招聘信息
如果你对“图存储”、“图学习”、“图计算”感兴趣,欢送给咱们投递简历,投递邮箱:zhaodengchang@meituan.com。
9 参考资料
- [1] Jim Webber, Emil Eifrem, Ian Robinson. Graph Databases(2nd Edition). O’Reilly Media, Inc. 2013: chapter 2.
- [2] Neo4j Database, https://github.com/neo4j/neo4j.
- [3] ArangoDB, https://github.com/arangodb/arangodb.
- [4] Virtuoso, https://github.com/openlink/virtuoso-opensource.
- [5] TigerGraph, https://github.com/tigergraph/ecosys.
- [6] RedisGraph, https://github.com/RedisGraph/RedisGraph.
- [7] JanusGraph, https://github.com/JanusGraph/janusgraph.
- [8] HugeGraph, https://github.com/hugegraph/hugegraph.
- [9] DGraph, https://github.com/dgraph-io/dgraph.
- [10] NebulaGraph, [https://github.com/vesoft-inc…
- [11] RDF, https://www.w3.org/RDF/](http…
- [11] RDF, https://www.w3.org/RDF/).
- [12] BadgerDB, https://github.com/dgraph-io/badger.
- [13] RocksDB, https://github.com/facebook/rocksdb.
- [14] LDBC-SNB 数据集:关联数据基准委员会提供的评测数据集,蕴含 26 亿顶点、177 亿关系.
- [15] NebulaGraph Architecture — A Bird’s View, https://nebula-graph.io/posts/nebula-graph-architecture-overview/.
- [16] An Introduction to NebulaGraph’s Storage Engine.
浏览美团技术团队更多技术文章合集
前端 | 算法 | 后端 | 数据 | 平安 | 运维 | iOS | Android | 测试
| 在公众号菜单栏对话框回复【2020 年货】、【2019 年货】、【2018 年货】、【2017 年货】等关键词,可查看美团技术团队历年技术文章合集。
| 本文系美团技术团队出品,著作权归属美团。欢送出于分享和交换等非商业目标转载或应用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者应用。任何商用行为,请发送邮件至 tech@meituan.com 申请受权。