成人一对一视频交友

主流开源分布式图形数据库基准

elbert
elbert

本文由美国代表团NLP团队的高晨和赵登昌撰写,首次发表于星云图官方论坛:https://discuss.nebula-graph.com.cn/t/topic/1377

image

1. 前言

近年来,深度学习和知识地图技术发展迅速。与深度学习的“黑箱”相比,知识地图具有高度的可解释性,广泛应用于搜索推荐、智能助手、金融风险控制等场景。美团在积累海量业务数据的基础上,结合使用场景,充分挖掘关联,逐步建立了美食地图、旅游地图、商品地图等近十个领域知识地图,登陆多业务场景,帮助当地生活服务智能化。

为了高效地存储和检索地图集数据,与传统的关系数据库相比,选择图形数据库作为存储引擎,在多跳查询中具有明显的性能优势。目前业界知名的图形数据库产品有几十款。选择一款能够满足美团实际业务需求的图形数据库产品,是搭建图形存储和学习平台的基础。根据目前的业务情况,我们制定了选择的基本条件:

开源项目,对商业应用友好

只有对源代码进行控制,才能保证数据的安全性和服务的可用性。

支持集群模式,具备存储和计算的横向扩展能力

美团地图集业务数据量可达1000多亿点边,吞吐量可达数万qp。单节点部署无法满足存储要求。

能够服务 OLTP 场景,具备毫秒级多跳查询能力

美团搜索场景中,为了保证用户的搜索体验,严格限制每个链接的超时时间,不能接受二级以上的查询响应时间。

具备批量导入数据能力

地图集数据通常存储在数据仓库中,如Hive。必须要有一种手段将数据快速导入到图形存储中,才能保证服务的时效性。

我们在DB-Engines网站上试用了排名前30的图形数据库产品,发现大部分知名的开源版本的图形数据库都只支持单节点,不能横向扩展存储,不能满足大规模图形数据的存储要求,如secondary、ArangoDB、Virtuoso、TigerGraph、RedisGraph等。经过调查对比,最终纳入评估范围的产品有:星云图(原阿里巴巴团队开发)、Dgraph(原谷歌团队开发)、HugeGraph(百度团队开发)。

2. 测试概要

2.1 硬件配置

数据库实例:运行在不同物理机器上的Docker容器。

单实例资源:32核,64GB内存,1TB SSD存储。[英特尔至强金5218 CPU @ 2.30GHz ]

实例数:3

2.2 部署方案

星云v1.0.1

Metad负责管理集群元数据,Graphd负责执行查询,stored负责Storaged的数据分片。RocksDB用于存储后端。

Dgraph v20.07.0

Zero负责管理集群元数据,Alpha负责查询和存储。存储后端是Dgraph自己的实现。

HugeGraph v0.10.4

HugeServer负责管理集群元数据和查询。而HugeGraph支持RocksDB后端,不支持RocksDB后端的集群部署,所以存储后端采用HBase。

3. 评测数据集

image

社会地图集数据集:https://github.com/ldbc

生成参数:分支=稳定,版本=0.3.3,规模=1000

实体情况:4类实体,共26亿

关系情况:19种关系,共计177亿

数据格式:csv

GZip压缩尺寸:194克

4. 测试结果

4.1 批量数据导入

4.1.1 测试说明

批量导入的步骤是:Hive仓库底部的csv文件-图形数据库支持的中间文件-图形数据库。每个图形数据库的具体导入方法如下:

星云:执行Spark任务,从数据仓库生成存储在RocksDB底部的sst文件,然后执行sst摄取操作插入数据。

Dgraph:执行Spark任务,从数据仓库生成三重rdf文件,然后执行批量加载操作,直接生成各个节点的持久文件。

HugeGraph:支持直接从几个仓库的csv文件导入数据,所以不需要统计仓库和中间文件的步骤。通过加载程序批量插入数据。

4.1.2 测试结果

image

4.1.3 数据分析

星云:数据存储的分布模式是主键hash,各节点存储分布基本均衡。导入速度最快,存储放大率最好。

Dgraph:原来的194G数据是在392G内存的机器上导入的,8.7h后OOM退出,不可能全部导入。数据存储的分布模式是三重谓词,同一关系只能存储在一个数据节点上,导致存储和计算严重偏斜。

HugeGraph:导入了原来的194G数据,写入了一个节点为1000G的磁盘,导致导入失败,整个数据量无法导入。存储倍率最差,数据歪斜严重。

4.2 实时数据写入

4.2.1 测试说明

向图形数据库中插入点和边,以测试实时写入和并发性。

响应时间:固定5万条数据,用固定的qp发出写请求,所有的数据都会发出。从发送请求到接收响应,获取Avg、p99和p999需要时间。

最大吞吐量:固定的1,000,000条数据,随着发送写请求的qp的增加,查询被回收。以1分钟内成功请求的峰值qp为最大吞吐量。

插入点

星云插入顶点t_rich_node (creation_date,first_name,last_name,gender,生日,location_ip,browser _ used)VALUES $ { mid } :(‘ 2012-07-18t 01336016336017.119 0000 ‘,’ Rodrigo ‘,’ Silva ‘,’女’,’ 1984-10-11 ‘,’ 84.194.222.86 ‘,’ Firefox ‘)

Dgraph {

设置{

${mid}创建_日期’ 2012-07-18t 01:16336017.119 0000 ‘。

${mid}名字“Rodrigo”。

${mid}姓氏’ Silva ‘。

${mid}性别“女性”。

${mid}生日’ 1984-10-11 ‘。

$ { mid } location _ IP ‘ 84 . 194 . 222 . 86 ‘。

${mid} browser_used ‘Firefox ‘。

{}

{}

hughegraph g . addvertex(t . label,’ t_rich_node ‘,T.id,${mid},’ creation_date ‘,’ 2012-07-18t 01:16336017.119 0000 ‘,’ first_name ‘,’ Rodrigo ‘,’ last_name ‘,’ Silva ‘,’ gender ‘,’女’,’生日’,’ 1984-10-11 ‘,’ location_ip ‘,’ 84.194.222.86 ‘,’ browser_used ‘,’ Firefox ‘)

插入边缘

星云INSERT EDGE t _ EDGE()VALUES $ { mid 1 }-$ { mid 2 } :();

Dgraph {

设置{

${mid1}链接${mid2}。

{}

{}

HugeGraph g.V(${mid1})。as(‘src ‘)。V(${mid2})。ADd(‘ t _ edge ‘)。from(‘src ‘)

4.2.2 测试结果

实时书写

image

image

4.2.3 数据分析

星云:如第4.1.3节分析所述,星云的写请求可以

由多个存储节点共享,响应时间和吞吐量大大提高。

Dgraph:如4.1.3节的分析所述,相同的关系只能存储在一个数据节点上,吞吐量很差。

HugeGraph:由于存储后端基于HBase,其实时并发读写能力低于RocksDB(星云)和BadgerDB (Dgraph),所以性能最差。

4.3 数据查询

4.3.1 测试说明

常见的N跳查询返回ID,N跳查询返回属性,常见的朋友查询请求测试图形数据库的读取性能。

响应时间:固定5万个查询,读取请求按固定qp发送,发送完所有查询就结束了。从发送请求到接收响应,获取Avg、p99和p999需要时间。

60s内未返回的结果为超时。

最大吞吐量:1,000,000个查询是固定的,读取请求通过增加qp发送,查询被回收。以1分钟内成功请求的峰值qp为最大吞吐量。

缓存配置:所有参与测试的图形数据库都有读缓存机制,默认打开。在每次测试前重新启动服务,以清除缓存。

多跳查询返回标识

星云GO $ { n } STEPS FROM $ { mid } OVER person _ known _ person

Dgraph {

q(func : uid($ { mid }){

uid

Person_knows_person {#${n}跳数=嵌套级别

uid

{}

{}

{}

Hugegraph g.v ($ {mid})。out()。id () # $ {n}跳数=out()链长

n跳查询返回属性

星云GO $ { n } STEPS FROM $ { mid } OVER person _ knows _ person YIELDperson _ knows _ person . creation _ date,$$.person.first_name,$$.person.last_name,$.person.gender,$.person .生日,$$.person.location_ip,$.person.browser_used

Dgraph {

q(func : uid($ { mid }){

uid first_name last_name性别生日地点_ip浏览器_已使用

Person_knows_person {#${n}跳数=嵌套级别

uid first_name last_name性别生日地点_ip浏览器_已使用

{}

{}

{}

Hugegraph g.v ($ {mid})。out () # $ {n}跳数=out()链长

常用好友查询语句

星云GO FROM $ { mid 1 } OVER person _ known _ person INTERSECT GO FROM $ { mid 2 } OVER person _ known _ person

Dgraph {

var(func : uid($ { mid 1 }){

person_knows_person {

M1作为uid

{}

{}

var(func : uid($ { mid 2 }){

person_knows_person {

M2作为uid

{}

{}

in _ common(func : uid(M1))@ filter(uid(M2)){

uid

{}

{}

HugeGraph g.V(${mid1})。out()。id()。聚合(‘ x ‘)。V(${mid2})。out()。id()。其中(在(‘ x ‘)内)。dedup()

4.3.2 测试结果

多跳查询返回标识

image

image

n跳查询返回属性

单个返回节点的平均属性大小为200字节。

image

image

普通朋友这个项目没有测试最大吞吐量。

image

4.3.3 数据分析

在1跳查询返回ID的“响应时间”实验中,星云和DGraph只需要进行一次边搜索。由于DGraph的存储特性,相同的关系存储在单个节点中,1跳查询不需要网络通信。而星云的实体分布在很多节点,所以实验中DGraph的响应时间比星云稍好。

在1跳查询返回ID“最大吞吐量”的实验中,DGraph集群节点的CPU负载主要落在存储关系的单个节点上,导致集群CPU利用率低,因此最大吞吐量只有星云的11%。

在2跳查询“响应时间”实验中,由于上述原因,DGraph在qps=100时已经接近集群负载能力上限,因此响应时间大大减慢,是星云的3.9倍。

在1-hop查询返回属性实验中,星云只需要搜索【输出边总数Y】次,因为它将实体的所有属性作为一个数据结构存储在单个节点上。而DGraph把实体的所有属性都看作边,分布在不同的节点上,需要搜索边【属性个数X *边总数Y】次,所以查询性能比星云差。多跳查询也是如此。

在普通朋友实验中,由于这个实验基本相当于两个1-hop查询返回的ID,所以测试结果比较接近,不再赘述。

由于HugeGraph存储后端基于糖化血红蛋白,实时并发读写能力低于岩石星云和BadgerDB (Dgraph),因此在多项实验中性能表现均落后于星云和DGraph。

5. 结论

参与测试的图数据库中,星云的批量导入可用性、导入速度、实时数据写入性能、数据多跳查询性能均优于竞品,因此我们最终选择了星云作为图存储引擎。

6. 参考资料

星云基准:https://discuss.nebula .星云。星云-graph.com.cn/t/topic/782

星云公共卫生基准微信团队:https://discuss.nebula .星云。星云-graph.com.cn/t/topic/1013

DGraph Benchmark:https://DGraph。io/博客/标签/基准/

巨图基准:https://巨图。github。io/巨图-doc/性能/巨图-Benchmark-0。5 .6 .html

tiger graph Benchmark:https://www .老虎图。com/Benchmark/

RedisGraph Benchmark:https://redis labs。com/blog/new-RedisGraph-1-0-reasons-600 x-fast-performance-graph-databases/

本次性能测试系美团NLP团队高辰、赵登昌撰写,如果你对本文有任意疑问,欢迎来原贴和作者交流:https://discuss.nebula .星云。星云-graph.com.cn/t/topic/1377

elbert
品牌