Nebula Graph:一个开源的分布式图数据库。做为惟一可以存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不只可以在高并发场景下知足毫秒级的低时延查询要求,还可以实现服务高可用且保障数据安全性。git
HBaseCon Asia2019 活动于 2019 年 7 月 20 日于北京金隅喜来登酒店举办,应主办方邀请,Nebula Graph 技术总监-陈恒在活动中发表演讲 “Nebula: A Graph DB based on HBase” 。本篇文章是根据这次演讲所整理出的技术干货,全文阅读须要 30 分钟。github
你们下午好,我是陈恒,来自 VESoft,是开源图数据库 Nebula Graph 的开发者。同时,我也是 HBase 的 Commiter<del>(刚才在后面和各位大佬谈笑风生)</del>,今天和你们分享的,是咱们最近刚开源的分布式图数据库 Nebula Graph。算法
首先,介绍一下咱们公司:欧若数网科技有限公司(英文名:VESoft),是 2018 年 10 月份成立的。咱们的核心产品是分布式图数据库 Nebula Graph,这个项目从开始到如今,大概作了半年多时间。目前已经 release alpha 版本,还有能够试用的 docker,正式的 release 预计会在 10 月份。docker
NebulaGraph 是彻底开源的,能够在 GitHub 上访问 https://www.github.com/vesoft-inc/Nebula数据库
下面咱们看一张图,是 DB-Engine 的统计,反映了从 2013 年到今年全部的 NoSQL 类数据库的发展趋势。横轴表明的是时间,纵轴能够认为是受众程度,或者社区里的讨论热烈程度。你们能够看到绿色的线就是图数据库。这些年一共翻了十倍,增加仍是很是迅猛的。后端
在座的同事是 HBase 专家,部分可能对于图数据库有些不太了解,我这里简单介绍一下图数据库。它的主要应用场景实际上是针对于各类各样的点和边组成的数据集合。缓存
举几个例子来说,典型图数据库的应用场景有如下几个。安全
社交场景是一个咱们常见的社交场景,就是好友之间的关系。这个天然而然构成了一张图。好比说:在社交场景里面,作推荐算法。为某我的推荐他的好友。如今典型的方法都是去找好友的好友,而后看好友的好友有没有可能成为新的好友。这里面可能会有各类亲密度关系,以及各类各样的排序。传统来说,咱们可能会利用 MySQL 或者是 HBase 存各类各样的好友关系,而后经过多个串行的 Key Value 访问来查。可是真正在线上场景里面的话,是很难知足性能要求的。因此,另一种作法是利用离线计算。把可能的好友关联和推荐都离线计算好。而后,查的时候直接去读已经准备好的数据,但这个问题就在于时效性比较差。对于有一些对于时效性要求比较高的场景,这样是不能够接受的。后面我有一些 case 能够来谈这个事情。网络
商业关系网络:数据库的使用场景除了社交网络外,还有商业关系网络也很常见。在金融和风控领域,商业关系实际上是很典型的一张图,多个公司之间有贸易往来,公司和银行之间也有往来。好比说一个公司去银行申请贷null款的时候,银行在审查这家公司可能自己没有什么问题,可是这家公司可能控制或者被控制的其余公司,或者整个集团的其余子公司,早已经进入了黑名单,甚至要控制一组相互担保的公司之间的整体贷款额度。这个时候就须要构成一些风控的功能来拒掉这笔贷款。商业关系里面还有人与人之间的转帐关系,好比去查一个信用卡反套null现的网络。很典型的一个网络社群就是:A 转帐到 B,B 转帐到 C,C 又转让回 A 就是一个很典型的一个环。更多的黑产可能会是一个很大的黑产社区。对于这样的闭环,这类查询在图数据库大规模应用以前,大部分都是采用离线计算的方式去找。可是离线场景很难去控制当前发生的这笔交易。例如一个信用卡交易或者在线贷null款,整个做业流程很长,在反套null现这块的审核时间可能只有秒级。这也是图数据库很是大的一个应用场景。架构
知识图谱:除了商业关系还有一个就是知识图谱。知识图谱这个概念提出来已经很早了,大概是在 2004,2005 年的时候,Google 把本身的 search engine 慢慢的从倒排转到知识图谱上。这样在 search 的时候能够回答一些问题,好比说今天的天气怎么样?好比说如今谁的老婆的外甥的二大爷是谁。根据一些相似于问题式的知识,而不是基于关键字进行 search。知识图谱这几年很是的火,主要的缘由就是一些垂直领域,慢慢的发现知识图谱很是的有价值。好比说:在金融领域上会有本身金融领域的知识图谱,结合一些 NLP 技术作大量的财报自动分析,或者像 Kensho 这样的新闻事件驱动自动生成分析报表和投资建议;还能够作一些投资组合,发现一二级市场公司内的关联关系,财务造假或者地方债暴雷形成的风险传播。再好比不少作在线教育的同事可能知道,在线教育的领域里面也有很多知识图谱。好比说有哪些考点,这个题是属于哪些考点,考点之间是怎么关联起来的,作错的考点附近的知识点都须要增强,这样也是一张关系网络。也是图数据库一个普遍应用的场景。
IoT 物联网(Internet of Things)是目前很是火的。之前,每个设备都是单纯的 Device,设备和设备之间是没有关系的。可是,物联网的出现打通了这些设备之间的关系。好比:帐号和设备都是有绑定关系的,帐号和帐号之间又有必定的关系,经过这样设备之间也能够创建出一张网络来。
通常来讲,图数据库并非简单的关联关系查询,在图遍历的过程,一般要根据属性作一些计算。因此一个单单的图关联是彻底不能知足要求的。举个例子,这是一个股票新闻实时推荐的场景。
你们知道通常散户炒股并非高频这样事件驱动的,可是他们也会边看新闻边盯着 K线。因此在这个时候要给他们推荐一些什么新闻呢。通常常见的办法是爬虫得到新闻,清洗完毕后,NLP 分词,提取出关键词后,而后跟股票代码关联上。通常根据监管,可能还要加上一些编辑审核和推送。但你们知道中国股市好的时候,是线下口口相传的。因此有个思路是经过好友圈来推荐新闻:首先会去找用户的好友,而后这些好友可能浏览过一些文章,那么根据驻留时间等,好友对这个文章可能会有一个评分,这个评分用 WL 来表示。好友和好友之间也有必定的亲密度,用 WC 表示。这个亲密度能够来源于以前的聊天次数、转帐次数等。同一我的到一篇文章之间可能会有多条路径。好比说到第二篇文章,可能会有几十条路径。因此说这么多条路径的权值之和表明了我和这篇文章的之间的评分。最终给用户推荐文章的时候,但愿是把全部的计算结果作 Top N。从线上的结果来看,转化效率比其余几种都要高。
再回到技术底层,图数据库面临的技术挑战。
一个挑战就是极低的 latency 和极高的 throughput。好比说查寻好友的好友这样的两跳场景,咱们的 Nebula Graph 能在十毫秒之内返回,同时能作到单机 10 万的 pps。
另一个挑战就是数据量。一个典型的银行金融图谱,数据量已经能够达到百 T 规模,大概是几十亿个点和千亿条边的规模。固然,若是图自己只是存点 ID 和点 ID 之间的关联关系,这样的数据量千亿级别其实单机也能存储。可是实际上就像刚才说的,光纯点和边是不够的,还须要有不少图属性作分析,这样单机是确定不够的。另外就是数据量增加的速度至关快,即便今天单机作个 POC 能存下,可能几个月以后又要扩容了。
还有一个挑战就是如今愈来愈复杂的商业逻辑,用传统的数据库去分析,基本上每个逻辑都要写 Java 代码来完成查询数据。咱们但愿不要那么依赖于开发人员,分析人员能够像写 SQL 同样,本身能够搞定。
最后一个挑战就是关于高可用要求。图数据库刚开始出现的时候,基本上就是一个二级索引。至关于只缓存了点和边之间的关系,真正的属性多是在别的地方(好比 HBase 或者 MySQL 里面)。Data 自己的正确性和高可用都是都是依赖于这些组件的。但随着使用场景愈来愈多,这样分离的存储方式性能跟不上,天然就但愿数据直接放在图数据库里面。那么各类传统数据库和分布式系统要面临的技术问题也要解决。好比数据多副本的强一致性问题,ACID。对于图数据库的要求愈来愈多,客户更但愿做为一个数据库,而不是做为一个索引或者关系 cache。
对于 Nebula Graph 来说,有这么几个技术特色:第一个就是采用了存储计算分离的架构。这样架构主要的考虑其实前面几个 Talk你们都已经讨论了不少,主要好处就是为了上云或者说 弹性
, 方便单独扩容
。上午的 Talk:HBase on Cloud 也有提到,业务水位老是很难预测的,一段时间存储不够了,有些时候计算不够了。在云上或者使用容器技术,计算存储分离的架构运维起来会比较方便,成本也更好控制。你们使用 HBase 那么久,这方面的感触确定不少。
Nebula Graph 的第二个技术特色是它的查询语言,咱们称为 nGQL,比较接近 SQL。惟一大一点的语法差别就是 不用嵌套
(embedding)。你们都知道嵌套的 SQL,读起来是很是痛苦的,要从里向外读。
第三个特色就是 Nebula Graph 支持多种后端存储,除了原生的引擎外,也支持 HBase。由于不少用户,对 HBase 已经至关熟悉了,并不但愿多一套存储架构。从架构上来讲,Nebula Graph 是彻底对等的分布式系统。
和 HBase 的 CoProcessor 同样,Nebula Graph 支持数据计算下推。数据过滤,包括一些简单的聚合运算,可以在存储层就作掉,这样对于性能来说能提高会很是大。
多租户,Nebula Graph是经过多 Space 来实现的。Space 是物理隔离。
除了图查询外,还有很常见的一种场景是全局的属性查询。这个和 MySQL 同样,要提高性能的主要办法是为 属性创建索引
,这个也是 Nebula Graph 原生支持的功能。
最后的技术特色就是关于图算法方面。这里的算法和全图计算不太同样,更可能是一个子图的计算,好比最短路径。你们知道数据库一般有 OLTP 和 OLAP 两种差别很大的场景,固然如今有不少 HTAP 方面的努力。那对于图数据库来讲也是相似,咱们在设计 Nebula Graph 的时候,作了一些权衡。咱们认为全图的计算,好比 Page Rank,LPA,它的技术挑战和 OLTP 的挑战和对应的设计相差很大。咱们但愿 Nebula Graph 可以在 OLTP 这块提供最好的表现。
下面为你们介绍 Nebula Graph 的架构图:下图(图1)是基于原生存储的,图3 是基于 HBase 的,有一些不一样。
这条虚线上面是计算层,下面是存储层。
图 1:基于原生存储的架构图
咱们先看下计算层,计算层能够理解为把一个 query 翻译成真正须要的执行计划,产生执行计划以后,到下面存储层拿须要的数据。这和传统数据库很是相似,查询语言也很相似。这里面比较重要的事情是查询优化,除了前面提到的计算下推到存储层外,目前一个主要的实现是并发执行。
图 2:Query Service
举个例子,查好友的大于 18 岁的好友,可能好友有不少,没有必要等一度好友都返回后,再去查二度好友。固然应该异步来作,一度好友部分返回后,就马上开始二度查询。有点相似图计算里面的 BSP 和 ASP。这个优化对提高性能有很是大做用。对于 Storage 层来讲,又分为上面的 Storage Engine 和 KV Store。由于 Nebula Graph 是分布式系统,数据是分片的。目前的分片方法是静态哈希,和 HBase 不同。主要是由于图查询基本都是特定 Prefix 的 Scan,Get 不多。好比一我的的好友这样,就是同一个 prefix 的 scan。每个数据分片会经过 RAFT 协议来保证数据的强一致。这和 HBase 写到底层 HDFS 也不同。3 台机器上的 Partition1 组成一个 Raft Group。Storage Engine 作的事情比较简单,就是把图语义的查询请求翻译成 KV 的查询请求。关于图右边的 Meta Service,它的主要做用是 schema 管理和集群管理。Nebula Graph 中的点和边都是有属性和版本的,那每一个属性的类型和版本在 MetaService 中统一管理。集群管理主要用于运维和鉴权目的,负责机器上下线和对用户作 ACL。
图 3:基于 HBase 的架构图
Nebula Graph 的 HBase 版本略微有些不同,能够看到虚线往下挪了,Storage Service 嵌入到 Query Engine 里面,这是由于 HBase 是独立的服务,Storage Service 进程能够和 Query Engine 放同一台机器上,直接一对一服务了。另外,由于 HBase 本身有 partition,就不必再分一次了。
下面介绍下 Nebula Graph 的数据模型和 Schema(每种标签有一组相对应的属性,咱们称之为 schema)。前面说到 Nebula Graph 是有向属性图,点和边都有各自属性。点有点属性,Nebula Graph 里面称为 Tag(类型),点能够有多种类型,或者叫多种 Tag。好比一个点既能够是 Tag Person,有属性姓名、年龄;也是 Tag developer,属性是擅长的语言。Tag 是能够像类同样继承的,一个 Tag 继承自另一个 Tag。边和点略微有点不同,一条边只能有一种类型。可是两个点之间能够有多种类型的边。另外,像 TTL 这种功能,Nebula Graph 也是支持的。Nebula Graph 的数据模型和 Schema
!这里须要提一下,对于 HBase 和 Nebula Graph 原生存储来讲,Schema Version 处理上是不同的。HBase 是没有 Schema 的。
强 Schema 最大的好处,是知道这条数据何时结束的,一行有多少属性是知道的。因此在根据某个版本号取数据的时候,从某一行跳到下一行,不须要对每一个属性都扫描一遍。但若是像 HBase 这样弱 Schema 系统,性能消耗是很是大。但相应的,问题就来了,若是要支持强 Schema,要变动 Schema 怎么办?更改 Schema 在 MySQL 里面,每每要锁表的。对于 Nebula Graph 来讲,当更改 Schema 时,并非在原来的数据上进行更改,而是先插入一个新的 Schema,固然这要求写入数据的时候就要记录版本号。这样的话在读的时候,才能知道要用版本。
再解释一下关于 Key 的设计,点和边的 Key 设计是像上面两行这样,一个点是一个 Key,一条边是两个 Key,这样的目的是把起点和出边存在一块儿,对端的终点和入边存储在一块儿。这样在查询的时候,能够减小一次网络。另外,对于 Nebula Graph 原生存储和 HBase 存储,属性采用的存储方式也是不同的。在 HBase 里面,一个属性放在一个 Column 里面。在原生存储里面,全部属性放在一个 Column 里面。这样设计的主要缘由是,若是用户使用 HBase 做为底层存储,其实他更指望 HBase 这张表在别的系统里面也能够用,因此说咱们考虑把它打散开了。
最后讲一下咱们的 Query Language:nGQL
咱们说它比较相似 SQL,好比说看这个例子,从某一个点开始向外拓展,用 nGQL 来写就是,GO FROM $id,起始点,而后 OVER edge,沿着某条边,还能够设置一些过滤条件,好比说,从这个点出发,沿着个人好友边,而后去拿,里面年龄大于十八岁的。
那要返回哪些属性?能够用 YIELD,好比说年龄,家庭住址。前面提到,不但愿嵌套,嵌套太难读了,因此做为替代, Nebula Graph 用 PIPE 管道。前一条子查询的结果,PIPE 给第二条,而后第二条能够 PIPE 给第三条。这样从前日后读起来,和咱们人的思考顺序是同样的。可是管道只解决了一个输入源的问题。
多个输入源的时候怎么办?Nebula Graph 还支持定义某个变量,这个和存储过程有点像。像上面这样,把 $var 定义成一个子查询的结果,再把这个结果拿去给其余子查询使用。还有种很常见的查询是全局匹配,这个和 SQL 里面的 SELECT … FROM … WHERE 同样,它要找到全部知足条件的点或者边。咱们这里暂时取名叫作 FIND。你们要是以为其余名字好也能够在 GitHub 上给咱们提 issue。
最后就是一些 UDF,用户本身写的函数,有些复杂的逻辑用 SQL 可能很差描述,Nebula Graph 也但愿支持让用户本身写一些代码。由于咱们代码是 C++ 写的,再考虑到用户群体,作数据分析用 Python 比较多,咱们考虑先支持 C++ 和 Python。
现场参会者提问:大家这个架构是 TinkerPop 的实现嘛?区别在哪里?
陈恒的回复以下:
不是的。咱们是彻底自研的。
首先咱们查询语法并非 Gremlin 那样命令式的,而是更接近 SQL 这种描述式的。能够说下咱们的思考,咱们主要考虑了查询优化的问题。
你知道像 Gremlin 那样的命令式语言,query 是 .in() .out() 这样一步步组成的,因此查询引擎只能按照给定的命令一步步把数据捞上来,每次序列化速度都很慢的,像 Titan 那样。咱们的测试结果应该有几十倍的性能差距。
另外既然用户每步指令是明确的,查询引擎要作优化很难,要很是智能推测出用户整一串指令的最终指望才能优化,这样难度比较高。这个有点像编译器的优化,优化错就很麻烦了。
咱们但愿像 SQL 这样描述式的,用户说明最终目的就行,怎么处理交给执行引擎来优化,这样作优化比较容易完善,可借鉴的算法也比较多。
固然也和咱们以 C++ 作开发语言有关。咱们也有想过作 Gremlin 和 nGQL 之间的 driver,主要看社区,欢迎给咱们提 issue
上面就是本次 Nebula Graph 参会 HBaseCon Asia2019 的所有内容,最后和你们再说下 Nebula Graph 是彻底开源的项目,对于图数据库比较感兴趣的同窗能够加 wechat 讨论群,或者在 GitHub 上提 Issue,也欢迎你们给咱们支持 star 项目。
Nebula Graph:一个开源的分布式图数据库。