图数据结构,可以更好地表征现实世界。美团业务相对较复杂,存在比较多的图数据存储及多跳查询需求,亟需一种组件来对千亿量级图数据进行管理,海量图数据的高效存储和查询是图数据库研究的核心课题。本文介绍了美团在图数据库选型及平台建设方面的一些工做。
图数据结构,可以很天然地表征现实世界。好比用户、门店、骑手这些实体能够用图中的点来表示,用户到门店的消费行为、骑手给用户的送餐行为能够用图中的边来表示。使用图的方式对场景建模,便于描述复杂关系。在美团,也有比较多的图数据存储及多跳查询需求,归纳起来主要包括如下 4 个方面:前端
整体来讲,美团须要一种组件来管理千亿级别的图数据,解决图数据存储以及多跳查询问题。海量图数据的高效存储和查询是图数据库研究的核心课题,如何在大规模分布式场景中进行工程落地是咱们面临的痛点问题。传统的关系型数据库、NoSQL 数据库能够用来存储图数据,可是不能很好处理图上多跳查询这一高频的操做。git
Neo4j 公司在社交场景(见图1)里作了传统关系型数据库 MySQL 跟图数据库 Neo4j 的查询性能对比 [1],在一个包含 100 万人、每人约有 50 个朋友的社交网络里找最大深度为 5 的朋友的朋友,实验结果代表多跳查询中图数据库优点明显(见图 2)。然而选取或者自主研发一款高吞吐、低查询延时、能存储海量数据且易用的图数据库很是困难。下面将介绍美团在图数据库选型及平台建设方面的一些工做。github
在图数据库的选型上咱们主要考虑了如下 5 点:(A) 项目开源,暂不考虑需付费的图数据库;(B) 分布式架构设计,具有良好的可扩展性;(C) 毫秒级的多跳查询延迟;(D) 支持千亿量级点边存储;(E) 具有批量从数仓导入数据的能力。算法
分析 DB-Engines[2] 上排名前 30 的图数据库,剔除不开源的项目,咱们将剩余的图数据库分为三类:数据库
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 集群包含三类服务,即 Query Service、Storage Service 和 Meta Service。每类服务都有其各自的可执行二进制文件,既能够部署在同一节点上,也能够部署在不一样的节点上。下面是NebulaGraph 架构设计(见图 3)的几个核心点16。数据结构
NebulaGraph 基于 C++ 实现,架构设计支持存储千亿顶点、万亿边,并提供毫秒级别的查询延时。咱们在 3 台 48U192G 物理机搭建的集群上灌入 10 亿美食图谱数据对 NebulaGraph 的功能进行了验证。架构
为了统一管理图数据,减小工程同窗在图数据库集群上的运维压力,咱们基于开源分布式图数据库 NebulaGraph,搭建了一套一站式图数据库自助管理平台(见图 4),该平台包含如下 4 层:
数据存储层。 支持两种图数据库集群的部署。
与业界方案相比,团队主导设计的图数据库平台除了支持存储千亿顶点、万亿边,具有毫秒级别查询能力外,还提供了以下四项能力:应用可用性 SLA 达 99.99%;支持每小时百亿量级数据导入;实时写入数据时保证多集群数据最终一致性;易用的图谱可视化能力。下面将介绍具体的设计思路。
首先介绍单应用多集群高可用模块的设计(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,存储集群的当前状态。
第二个模块是每小时百亿量级数据导入模块,平台在 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、数据校验、增量回溯、数据版本切换、集群重启、数据预热。
第三个模块是实时写入多集群数据同步模块,平台约有 15% 的需求场景是在实时读取数据时,还要把新产生的业务数据实时写入集群,而且对数据的读写强一致性要求不高。就是说,业务方写到图数据库里的数据,不须要立马能读到。针对上述场景,业务方在使用单应用多集群这种部署方案时,多集群里的数据须要保证最终一致性。针对这一需求,咱们作了如下设计。
第一部分是引入 Kafka 组件,业务方在服务中经过 SDK 对图数据库进行写操做时,SDK 并不直接写图数据库,而是把写操做写到 Kafka 队列里,以后由该应用下的多个集群异步消费这个 Kafka 队列。
第二部分是集群在应用级别可配置消费并发度,来控制数据写入集群的速度。具体流程以下:
第三部分是在实时写入数据过程当中,平台能够同步生成一个全量数据版本,并作平滑切换(见图 9),确保数据的不重、不漏、不延迟。
第四个模块是图可视化模块(见图10),主要是用于解决子图探索问题。当用户在图数据库平台经过可视化组件查看图数据时,能尽可能经过恰当的交互设计来避免由于节点过多而引起爆屏。主要包括如下几个功能:
该项目数据是基于美团商户数据、用户评论构建的餐饮娱乐知识图谱,覆盖美食、酒店、旅游等领域,包含 13 类实体和 22 类关系。目前,点边数量大概在百亿级别,数据 T+1 全量更新,主要用于解决搜索或者智能助理里 KBQA(全称:Knowledge Based Question Answer)类问题。核心处理流程是经过 NLP 算法识别关系和实体后构造出 NebulaGraph SQL 语句,再到图数据库获取数据。
典型的应用场景包括商场找店,好比,某个用户想知道望京新荟城这个商场有没有海底捞,系统能够快速查出结果告诉用户;另外一个场景是标签找店,用户想知道望京 SOHO 附近有没有适合情侣约会的餐厅,或者能够多加几个场景标签,系统均可以帮忙查找出来。
该项目数据是基于医美商家信息构建的医美知识图谱,包含 9 类实体和 13 类关系,点边数量在百万级别,一样也是 T+1 全量更新,主要用于大搜底层实时召回,返回与 Query 相关的商户、产品或医生信息,解决医美类搜索词少结果、无结果问题。好比,某个用户搜“啤酒肚”这种症状、或者“润百颜”这类品牌,系统能够召回相关的医美门店。
该项目数据来自用户的画像信息、商户的特征信息、用户半年内收藏/购买行为,数据量级是 10 亿级别,T+1 全量更新。如今美团 App 和点评 App 上默认的商户推荐列表是由深度学习模型生成的,但模型并不会给出生成这个列表的理由,缺乏可解释性。
而在图谱里用户跟商户之间自然存在多条连通路径,项目考虑选出一条合适路径来生成推荐理由,在 App 界面上展现给用户推荐某家店的缘由。该项目基于用户的协同过滤算法来生成推荐理由,在家乡、消费水平、偏好类目、偏好菜系等多个组合维度中找出多条路径,而后给这些路径打分,选出一条分值较高的路径,以后按照特定 Pattern 产出推荐理由。经过上述方式,就能够得到“在北京喜欢北京菜的山东老乡都说这家店很赞”,或者“广州老乡都中意他家的正宗北京炸酱面”这类理由。
该项目把代码库中代码依赖关系写入到图数据库。代码库中存在不少服务代码,这些服务会包括对外提供的接口,这些接口的实现依赖于该服务中某些类的成员函数,这些类的成员函数又依赖了本类的成员变量、成员函数或者其它类的成员函数,那么它们之间的依赖关系就造成了一张图,能够把这个图写到图数据库里作代码依赖分析。
典型应用场景是精准测试:当开发同窗完成需求并向公司的代码仓库提交了 PR 后,能够把更改实时地写到图数据库中。这样的话,开发同窗就能查到他所写的代码影响了哪些外部接口,而且借助图可视化组件查看调用路径。若是开发同窗原本是要改接口 A 的行为,改了不少代码,可是他可能并不知道他改的代码也会影响到对外接口 B、C、D,这时候就能够用代码依赖分析来作个 Check,增长测试的完备性。
目前,图数据库平台基本具有了对图数据的一站式自助管理功能。若是某个业务方要使用这种图数据库能力,那么业务方能够在平台上自助地建立图数据库集群、建立图的 Schema、导入图数据、配置导入数据的执行计划、引入平台提供的 SDK 对数据进行操做等等。平台侧主要负责各业务方图数据库集群的稳定性。目前,美团有三四十个业务已经在平台上落地,基本知足了各个业务方的需求。
将来规划主要有两个方向,第一,根据业务场景优化图数据库内核,提高平台稳定性,开发的通用 Feature 持续反哺 NebulaGraph 社区。第二,挖掘更多的图数据价值。如今平台仅支持图数据存储及多跳查询这种基本能力,后续将基于 NebulaGraph 去探索图学习、图计算的能力,为平台用户提供更多挖掘图数据价值的功能。
登昌、梁帅、高辰、杨鑫、尊远、王超等,均为美团搜索与NLP部工程师。
若是你对“图存储”、“图学习”、“图计算”感兴趣,欢迎给咱们投递简历,投递邮箱:zhaodengchang@meituan.com。
阅读美团技术团队更多技术文章合集
前端 | 算法 | 后端 | 数据 | 安全 | 运维 | iOS | Android | 测试
| 在公众号菜单栏对话框回复【2020年货】、【2019年货】、【2018年货】、【2017年货】等关键词,可查看美团技术团队历年技术文章合集。
| 本文系美团技术团队出品,著做权归属美团。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者使用。任何商用行为,请发送邮件至tech@meituan.com申请受权。