图数据库的知识图谱:存储技术与实践完全指南!

  导读 创邻科技是一家致力于分布式原生图技术的公司,从 2016 年成立以来,一直在图存储和图计算领域深耕。

  创邻的图数据库产品 Galaxybase 已经为银行、电力、公安、互联网等行业的多家头部客户提gòng服务。

  大家知道世界万物是普遍联系的,Internet 带来了信息的连通,IoT 带来了设备的连通,像微信、微博、抖音、快手这些 APP 带来了人际关系的连通。

  随着社交、零售、金融、电信、物流等行业的快速发展,当今社会支起了一张庞大而复杂的关系网,在人们的生产和生活过程中,每时每刻都产生着大量的数据。

  随着技术的发展,我们对这些数据的分析和使用也不再局限于从统计的角度进行一些相关性的分析,而是希望从关联的角度揭示数据的一些因果联系。

  比如从社交网络分析里,我们可以做精准营销、好友推荐、舆情追踪等等;金融领域可以做信用卡反欺诈的分析,资金流向识别;零售领域,我们可以做用户 360 画像做商品实时推荐,返薅羊毛;电力领域,可以做电网的调度仿真、故障分析、电台因子计算;电信领域,可以做电信防sǎo扰,电信防诈骗;政企领域,可以做道路规划、智能交通,还有疫情精准防控;在制造业,我们可以做供应链管理、物流优化、产品溯源等;网络安全行业,可以做攻击溯源、调用链分析等等。

  比如企业的股权穿透分析,公安的安全案情分析,还有生物医药领域的基因分类和新药研发等等,这里就不一一赘述了。

  相比之下,RDF 的优势是可以支持多值属性,因为它的属性也是一个点,所以一个点连出去,可以有多值的属性。

  属性图的优势在于它两点之间可以表示同类型的多条边,因为它在边上是可以有区分属性的,边上的属性值也能让边上的表达能力更丰富。

  当然也有少量的图数据库是用 RDF 模型来做的,但是未来更多的新型图数据库都会用属性图模型。

  不论是用 RDF 还是用属性图,作为一个图数据库,它的核心目标是什么?或者说数据库存储需要解决的一个根本问题是什么呢?那些需要用关联分析的图场景,往往是一些数据规模大、关联跳数深、实时要求高的场景。

  在关联分析当中,不论是从一个起始点若干跳数内的邻域网络进行分析,还是对全图进行一些完整的计算,最核心的操作都是迭代遍历某个点的所有边,也就是所谓邻居的迭代遍历。

  在图数据库中,会直接存储边数据,也就是所谓的实现 index-free adjacency。

  查询的时候,迭代遍历一个点的所有邻居可以直接进行,不需要依赖于其它数据结构,从而可以大幅提升邻居迭代遍历的性能。

  这里是跟关系型数据库做的一个深点查询的性能对比,用的是 who-trust-whom 的一个公开数据集,这个数据集也不是很大,约 7.5 万点,50 万边。

  可以看出 2 跳的时候加索引可以明显提升关系型数据库的查询速度,到 3 跳的时候提升就不多了, 4 跳以上的时候加不加索引都会变得很慢。

  这就是图数据库的 index-free adjacency 的特性,能够大幅提升邻居查询的速度。

  上面的处理计算层和业务层都是以完全图的结构来描述,并且也不依赖于第三方存储组件,所以这种实现免索引连接的性能是最高效的。

  第二种方式是非原生存储,数据存储层使用的是一个第三方的开源存储组件,但是它在处理过程中实现了近似免索引连接,在大多数情况下也能提gòng不错的性能。

  第三种方式就是完全非原生的存储,底下可能是一个关系型数据库,或者是一个文档型或者其它类型的数据库,它的存储层其实并不是真正地实现了免索引连接,而是处理成通过索引或者一些其它技术手段,向上表达了一个图模型的查询接口。

  这种其实只是在接口层上实现了图的一个语义,而底下的存储和计算层都不是完全地使用免索引连接,所以它的性能也会相对低一些。

  在边文件中,是按照起始点的顺序存储点上对应的边,每条边存储的内容包括终止点 ID、边的 Meta 信息、边的一系列属性。

  这里所谓的 Meta 信息包括点边的类型、方向,还有一些为了实现事务的额外字段,这对于整体的存储来说不是特别重要,在这里就不详细展开了。

  这里的变长是由很多因素导致,比如两个点可能属性数量不一样,属性本身如果是字符串,长度也会不一样。

  属性长度不一样会导致每条边的存储空间也不一样,这样在边文件中就不能用一个简单的数组来进行寻址了。

  如果仅仅是属性导致的变长,还是有比较简单的解决方案的,比如可以把属性单独的再放到另一个存储文件中,这样点文件和边文件里面的内容,是不是定长的呢?其实也不一定,因为每个点上边的数量也是不一样的,所以在边文件里面,每个点触发的边序列的总长度也是不一样的。

  解决思路一般是两种,一种是使用额外的一个 offset 的记录,相当于是用一个偏移量记录,来记录每一个点或者边的起始位置。

  在链表方式的存储模式中,点和边全部存的都是 ID,包括点 ID、边 ID、属性 ID 等等。

  可以看到,是一个从点 A 到点 B 的边,A 是一个起始点,我们就去找起始点下一条边的 ID,就找到边 θ。

  我们看到,用链表存储的方式很好地解决了数组变长的问题,因为新增边的时候,只需要新增固定长度的结构组成链表即可。

  在链表存储方案下,每一次边迭代的时候,由于边 offset 的位置是随机的,所以会有大量的随机读操作。

  所以虽然这里理论上的迭代邻居找到下一条边的复杂度是 O(1),但 O(1) 的单位时间是磁盘随机读的时间,而不是顺序读的时间,这两者在性能上是会有非常大的差别的。

  所以使用这种链表的存储方式,通常来说会依赖一个非常高效实现的缓存机制,需要把大量的磁盘数据放到内存缓存中来读,在内存中进行随机访问的性能就会提升很多。

  它的读写操作流程如下:当一个请求进来的时候,直接写入内存中的一个 MemTable,如果 MemTable 没写满,就直接返回请求。

  从内存中直接写出来的第 0 层达到一定数据量大小的时候,或者触发某种条件的时候,就会进行一个归并排序,归并排序就是一个 Compaction 的过程。

  读取的时候是先去内存中的 MemTable 查找,找到了就返回,如果没有找到就去第 0 层的 SST 文件中查找,找不到再去第 1 层,这样逐层查找,一直到找到需要读取的 Key 为止。

  因为在 SST 文件中,Key 是有序排列的,所以我们需要通过 LSMTree 来实现免索引连接的能力。

  只要把边 Key 的最高位放起始点 ID,那么后面无论是边的其它什么信息,都可以让从起始点 ID 出发的边自然地排序排在一起。

  这里也可以加入一个编号的字段,因为两点之间,起始点和终止点 Meta 这些是固定的,编号字段加入之后,就可以支持在两点之间同类型的多条边共存。

  这种方法也比较适合在分布式场景下按类型做分片,这样同一类型的边就会排在相邻的分片中,有利于提高分布式查询的性能。

  首先是读性能,在读的时候,如果内存没有命中,下miàn是一个逐层的 SST 文件,去找 Key 的最坏情况,可能要把所有层的 SST 文件全部找完,才能找到合适的 Key。

  只有在理想情况下,比如在一个完整的 Compaction 完成的情况下,它才能真正实现免索引连接,否则会在各个 SST 文件内部去查找。

  而做 Compaction 又是一个有比较大的磁盘 IO 的操作,并且如果使用的是第三方的存储结构,那么做 Compaction 的操作是不受图数据库本身控制的,可能是由一些其它的机制触发的,比如是在前台负载压力比较大的情况下触发了 Compaction,这样实际在使用的时候会出现一些瓶颈,所以必须要对第三方存储进行比较深度的改动,才能够更好地优化。

  通过 LSM 树的方式写入速度快,但是读的时候又依赖于 Compaction 操作,在 Compaction 没有完成的情况下,它的读取速度也比较慢。

  通过链表的方式读取和写入速度都不占优,但是它的灵活性却最高,因为它是以 offset 形式的指针来实现的。

  还有一些其它的问题,比如分区分片、反向边一致性、如何支持事务、数据索引怎么做、数据过期等等,都是要解决的问题,实现起来还是比较复杂的。

  Galaxybase 是创邻研发的国产高性能分布式图平台,它的特点是速度快、高扩展、实时计算,支持一个知识中台,并且安全自主可控。

  使用原生分布式并行图存储,实现了存储层的免索引连接,可以毫秒级完成传统方案无法完成的深链分析,较同类技术有数百倍的提升。

  也内置了非常丰富的图算法,包括分布式图算法和单机图算法,不需要 ETL 就能实现实时图分析。

  存储层之上是计算层,实现了内置的图计算引擎,包含了单机的图算法和分布式图算法,并且还可以由用户来自定义一些定制化函数,来实现自己的高效算法。

  左侧可以看到,支持多源异构数据,比如传统关系库、CSV 文件、HDFS、实时流数据等等,都可以直接进行数据导入。

  Galaxybase 的一个性能优势,是能够高效地进行分布式图计算,并且实现了当前最大规模的图数据处理,实现了 5 万亿超大规模的分布式图存储。

  在线查询仅使用了 50 台机器的集群,出入度最大有 1000 万的超级节点,6 跳的平均查询时间仅为 6.7 秒。

  在 LDBC 的 SNB 测试里面,去年我们做了一个官方的 Audit,打破了一项世界记录,较之前的吞吐量提升 70%,平均查询性能有 6 倍以上的提升,最高的 95 分位查询性能提升达到 72 倍。

  Galaxybase 支持非常丰富的图算法,包括 57 种图算法,其中 28 种已经支持了分布式,其它一些分布式算法也正在实现中。

  我们的产品里面还包括一个图智能中台,主要是通过可视化界面的方式来进行交互式的探索,完成图的一些定性分析,包括搜索顶点、点边位置扩展、查找路径,还有各种混合的布局。

  我们提gòng各种图场景的解决方案,有很多合作伙伴,有很多已经在金融、能源、教育、互联网、政府多个行业中的头部客户落地的使用场景,并且已经服务了几年时间。

  Q1:针对大 value,比如大于 4K 的数据,随机读取的时候会非常耗 IO,这块有什么优化吗?

  A1:一般来说,图数据库里如果是一个属性值,单个属性值大于 4K,其实我们不建议把它放到图数据库中来,因为图数据库主要是做点边的关联邻居查找的。

  如果这个是要作为一个存储放进来的话,最好是把它单独放在一个另外的区域中,不要跟点边正常的这些属性来放在一起。

  通常情况下我们更多使用的是一个边切割,所以所有点的邻居都会存在一起,这样能更高效地来访问一个点的所有邻居。

  当一个点的邻居数量特别大的时候,这里可能都不只是 4K 量级,可能会有 400M 或者 4G 这样的量级,这种情况下的切割就会形成单个非常大的文件。

  这种时候也可以考虑动态的点切割的方式,就是把一个点的邻居,再切割成多个存储文件,存储文件可以在不同的分区里,可以在不同的分片下,这样就可以实现并行迭代的方式。

  当然这里的技术会更复杂,需要首先有对边进行唯一定位的能力,有这个能力之后,就可以在这一个点的所有邻居边上,再进行进一步的切割,然后把大文件再分成不同的小文件。

  在做这些计算的时候,就不是简单地返回路径,而是把路径上面的计算也一起做了,得到一个最后的计算结果。

  A3:肯定是有影响的,因为压缩毕竟也要占 CPU,所以这其实是个可选项,要看我们的需求是对读写性能更敏感,还是对磁盘空间更敏感。

  Q4:怎么做无 ETL 的实时图计算?如果直接从存储层迭代出来的数据怎么解决一致性的问题?如果用 snapshot 就会有 ETL。

  A4:可能要这样解释一下我们这个产品,它是存储、计算都包含的,它是自带了存储层和计算层,所以用 snapshot 不需要 ETL 过程,相当于我们自己的计算引擎可以去加载存储里面的数据,也不需要再做一个数据清理或者是转换的过程。

  一般我们在做一个图计算的时候,其实都是在一个 snapshot 上做图计算,不然整个计算结果也没有一致性。

  所以我们会加载图存储的某一个时间切片的一个时间点的 snapshot 到图计算引擎中,来做图计算。

  2023年6月27-28日9:00-17:00,2023亚马逊云科技中国峰会将在上海世博中心举办。

  本次峰会将会分享数百个技术话题与最佳实践,覆盖汽车、制造、金融、医疗与生命科学、电商、游戏、泛娱乐、电信、教育、数字化营销等领域。

赞(0)
未经允许不得转载:生活随想分享 » 图数据库的知识图谱:存储技术与实践完全指南!

生活随想分享生活随想分享