【图数据库实战】HugeGraph架构

news2024/10/7 8:28:53

一、概述

      作为一款通用的图数据库产品,HugeGraph需具备图数据的基本功能,如下图所示。HugeGraph包括三个层次的功能,分别是存储层、计算层和用户接口层。 HugeGraph支持OLTP和OLAP两种图计算类型,其中OLTP实现了Apache TinkerPop3框架,并支持Gremlin查询语言。 OLAP计算是基于SparkGraphX实现。

二、组件

      HugeGraph的主要功能分为HugeCore、ApiServer、HugeGraph-Client、HugeGraph-Loader和HugeGraph-Studio等组件构成,各组件之间的通信关系如下图所示。

  • HugeCore :HugeGraph的核心模块,TinkerPop的接口主要在该模块中实现。HugeCore的功能涵盖包括OLTP和OLAP两个部分。

  • ApiServer :提供RESTFul Api接口,对外提供Graph Api、Schema Api和Gremlin Api等接口服务。

  • HugeGraph-Client:基于Java客户端驱动程序。HugeGraph-Client是Java版本客户端驱动程序,后续可根据需要提供Python、Go、C++等多语言支持。

  • HugeGraph-Loader:数据导入模块。HugeGraph-Loader可以扫描并分析现有数据,自动生成Graph Schema创建语言,通过批量方式快速导入数据。

  • HugeGraph-Studio:基于Web的可视化IDE环境。以Notebook方式记录Gremlin查询,可视化展示Graph的关联关系。HugeGraph-Studio也是本系统推荐的工具。

三、设计理念

        常见的图数据表示模型有两种,分别是RDF(Resource Description Framework)模型和属性图(Property Graph)模型。RDF和Property Graph都是最基础、最有名的图表示模式,都能够表示各种图的实体关系建模。RDF是W3C标准,而Property Graph是工业标准,受到广大图数据库厂商的广泛支持。HugeGraph目前采用Property Graph。

      HugeGraph对应的存储概念模型也是参考Property Graph而设计的,具体示例详见下图:

      在HugeGraph内部,顶点仅存储Id不包含任何属性信息,顶点所有的属性和Label都通过边来存储。如图所示顶点(Id=1)有3个属性分别是name、age和lives,则由三条对应的边指向其具体的属性值,这三条边的Label和顶点属性名相同分别是name、age和lives。

      在HugeGraph内部,顶点与顶点之间的关系也通过边来存储的。但关系的属性并没有像顶点一样分来存储,而是和关系存储在一起。

      顶点属性值通过边指针方式存储时,如果要更新一个顶点特定的属性值直接通过覆盖写入即可,其弊端是冗余存储了VertexId;如果要更新关系的属性需要通过read-and-modify方式,先读取所有属性,修改部分属性,然后再写入存储系统,更新效率较低。从经验来看顶点属性的修改需求较多,而边的属性修改需求较少,例如PageRank和Graph Cluster等计算都需要频繁修改顶点的属性值。

四、 图分区方案

      对于分布式图数据库而言,图的分区存储方式有两种:分别是边分割存储(Edge Cut)和点分割存储(Vertex Cut),如下图所示。使用Edge Cut方式存储图时,任何一个顶点只会出现在一台机器上,而边可能分布在不同机器上,这种存储方式有可能导致边多次存储。使用Vertex Cut方式存储图时,任何一条边只会出现在一台机器上,而每相同的一个点可能分布到不同机器上,这种存储方式可能会导致顶点多次存储。

      采用EdgeCut分区方案可以支持高性能的插入和更新操作,而VertexCut分区方案更适合静态图查询分析,因此EdgeCut适合OLTP图查询,VertexCut更适合OLAP的图查询。HugeGraph目前采用EdgeCut的分区方案。

五、 VertexId 策略

      HugeGraph的Vertex支持三种ID策略,在同一个图数据库中不同的VertexLabel可以使用不同的Id策略,目前HugeGraph支持的Id策略分别是:

  • 自动生成(AUTOMATIC):使用Snowflake算法自动生成全局唯一Id,Long类型;

  • 主键(PRIMARY_KEY):通过VertexLabel+PrimaryKeyValues生成Id,String类型;

  • 自定义(CUSTOMIZE_STRING|CUSTOMIZE_NUMBER):用户自定义Id,分为String和Long类型两种,需自己保证Id的唯一性;

      默认的Id策略是AUTOMATIC,如果用户调用primaryKeys()方法并设置了正确的PrimaryKeys,则自动启用PRIMARY_KEY策略。启用PRIMARY_KEY策略后HugeGraph能根据PrimaryKeys实现数据去重。

     1.AUTOMATIC ID策略

schema.vertexLabel("person")

.useAutomaticId()

.properties("name", "age", "city")

.create();

graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");

     2.PRIMARY_KEY ID策略

schema.vertexLabel("person")

.usePrimaryKeyId()

.properties("name", "age", "city")

.primaryKeys("name", "age")

.create();

graph.addVertex(T.label, "person","name", "marko", "age", 18, "city", "Beijing");

3.CUSTOMIZE_STRING ID策略

schema.vertexLabel("person")

.useCustomizeStringId()

.properties("name", "age", "city")

.create();

graph.addVertex(T.label, "person", T.id, "123456", "name", "marko","age", 18, "city", "Beijing");

4.CUSTOMIZE_NUMBER ID策略

schema.vertexLabel("person")

.useCustomizeNumberId()

.properties("name", "age", "city")

.create();

graph.addVertex(T.label, "person", T.id, 123456, "name", "marko","age", 18, "city", "Beijing");

如果用户需要Vertex去重,有三种方案分别是:

  1. 采用PRIMARY_KEY策略,自动覆盖,适合大数据量批量插入,用户无法知道是否发生了覆盖行为

  2. 采用AUTOMATIC策略,read-and-modify,适合小数据量插入,用户可以明确知道是否发生覆盖

  3. 采用CUSTOMIZE_STRING或CUSTOMIZE_NUMBER策略,用户自己保证唯一

六、 EdgeId 策略

      HugeGraph的EdgeId是由srcVertexId+edgeLabel+sortKey+tgtVertexId四部分组合而成。其中sortKey是HugeGraph的一个重要概念。在Edge中加入sortKey作为Edge的唯一标识的原因有两个:

  1. 如果两个顶点之间存在多条相同Label的边可通过sortKey来区分

  2. 对于SuperNode的节点,可以通过sortKey来排序截断。

      由于EdgeId是由srcVertexId+edgeLabel+sortKey+tgtVertexId四部分组合,多次插入相同的Edge时HugeGraph会自动覆盖以实现去重。需要注意的是如果批量插入模式下Edge的属性也将会覆盖。

      另外由于HugeGraph的EdgeId采用自动去重策略,对于self-loop(一个顶点存在一条指向自身的边)的情况下HugeGraph认为仅有一条边,对于采用AUTOMATIC策略的图数据库(例如TitianDB)则会认为该图存在两条边。

HugeGraph的边仅支持有向边,无向边可以创建Out和In两条边来实现。

七 HugeGraph 事务处理

7.1 TinkerPop事务概述

      TinkerPop transaction事务是指对数据库执行操作的工作单元,一个事务内的一组操作要么执行成功,要么全部失败。详细介绍请参考TinkerPop官方文档:http://tinkerpop.apache.org/docs/current/reference/#transactions

7.2 TinkerPop事务操作接口
  • open 打开事务

  • commit 提交事务

  • rollback 回滚事务

  • close 关闭事务

7.3 TinkerPop事务规范
  • 事务必须显式提交后才可生效(未提交时修改操作只有本事务内查询可看到)

  • 事务必须打开之后才可提交或回滚

  • 如果事务设置自动打开则无需显式打开(默认方式),如果设置手动打开则必须显式打开

  • 可设置事务关闭时:自动提交、自动回滚(默认方式)、手动(禁止显式关闭)等3种模式

  • 事务在提交或回滚后必须是关闭状态

  • 事务在查询后必须是打开状态

  • 事务(非threaded tx)必须线程隔离,多线程操作同一事务互不影响

更多事务规范用例见:Transaction Test

7.4 HugeGraph事务实现
  • 一个事务中所有的操作要么成功要么失败

  • 一个事务只能读取到另外一个事务已提交的内容(Read committed)

  • 所有未提交的操作均能在本事务中查询出来,包括:

    • 增加顶点能够查询出该顶点

    • 删除顶点能够过滤掉该顶点

    • 删除顶点能够过滤掉该顶点相关边

    • 增加边能够查询出该边

    • 删除边能够过滤掉该边

    • 增加/修改(顶点、边)属性能够在查询时生效

    • 删除(顶点、边)属性能够在查询时生效

  • 所有未提交的操作在事务回滚后均失效,包括:

    • 顶点、边的增加、删除

    • 属性的增加/修改、删除

      示例:一个事务无法读取另一个事务未提交的内容

1. static void testUncommittedTx(final HugeGraph graph) throws InterruptedException {

2. final CountDownLatch latchUncommit = new CountDownLatch(1);

3. final CountDownLatch latchRollback = new CountDownLatch(1);

4. Thread thread = new Thread(() -> {

5. // this is a new transaction in the new thread

6. graph.tx().open();

7. System.out.println("current transaction operations");

8. Vertex james = graph.addVertex(T.label, "author",

9. "id", 1, "name", "James Gosling",

10. "age", 62, "lived", "Canadian");

11. Vertex java = graph.addVertex(T.label, "language", "name", "java",

12. "versions", Arrays.asList(6, 7, 8));

13. james.addEdge("created", java);

14. // we can query the uncommitted records in the current transaction

15. System.out.println("current transaction assert");

16. assert graph.vertices().hasNext() == true;

17. assert graph.edges().hasNext() == true;

18. latchUncommit.countDown();

19. try {

20. latchRollback.await();

21. } catch (InterruptedException e) {

22. throw new RuntimeException(e);

23. }

24. System.out.println("current transaction rollback");

25. graph.tx().rollback();

26. });

27. thread.start();

28. // query none result in other transaction when not commit()

29. latchUncommit.await();

30. System.out.println("other transaction assert for uncommitted");

31. assert !graph.vertices().hasNext();

32. assert !graph.edges().hasNext();

33. latchRollback.countDown();

34. thread.join();

35. // query none result in other transaction after rollback()

36. System.out.println("other transaction assert for rollback");

37. assert !graph.vertices().hasNext();

38. assert !graph.edges().hasNext();

39. }

   事务实现原理

  • 服务端内部通过将事务与线程绑定实现隔离(ThreadLocal)

  • 本事务未提交的内容按照时间顺序覆盖老数据以供本事务查询最新版本数据

  • 底层依赖后端数据库保证事务原子性操作(如Cassandra/RocksDB的batch接口均保证原子性)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1221346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言指针详解(1)(能看懂字就能明白系列)文章超长,慢慢品尝

目录 1、内存和地址 2、指针简介 与指针相关的运算符: 取地址操作符(&) 解引用操作符(间接操作符)(*) ​编辑 指针变量的声明 指针变量类型的意义 指针的基本操作 1、指针与整数相加…

解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题

参考博文:uniapp微信小程序无法使用本地静态资源图片(背景图在真机不显示)的解决方法_javascript技巧_脚本之家 问题:uniapp 开发微信小程序,当使用本地图片作为 background-image 时,真机无法显示 解决: 方法一&am…

在线预览excel,luckysheet在vue项目中的使用

一. 需求 需要在内网项目中在线预览excel文档,并可以下载 二.在项目中下载并引入luckysheet 1.打开项目根目录,npm i luckyexcel 安装 npm i luckyexcel2.在项目的index.html文件中引入依赖 外网项目中的引入(CDN引入)&#…

Cesium:绘制地质剖面

作者:CSDN @ _乐多_ 本文记录了根据地质剖面的三角网的点、索引和颜色数组,绘制地质剖面的框架和部分代码。 效果如下图所示, 文章目录 一、算法逻辑二、代码一、算法逻辑 将三角网的点、索引和颜色数组按规则排列好,输入到第二节的代码中,可以绘制一个面。将这个绘制函…

如何确保消息不会丢失

本篇文章大家还可以通过浏览我的博客阅读。如何确保消息不会丢失 - 胤凯 (oyto.github.io)很多人刚开始接触消息队列的时候&#xff0c;最经常遇到的一个问题就是丢消息了。<!--more-->对于大部分业务来说&#xff0c;丢消息意味着丢数据&#xff0c;是完全无法接受的。 …

骨传导耳机的优缺点是什么?有什么值得入手的骨传导耳机吗?

骨传导耳机的优点还是挺多的&#xff0c;比如说&#xff1a;佩戴舒适、避免听力损伤、使用更安全灯&#xff0c;在详细了解骨传导耳机有什么优点和缺点之前&#xff0c;先来认识一下什么是骨传导耳机。 骨传导耳机是一种通过人体骨骼来传递声音的耳机&#xff0c;与传统的耳机相…

23111710[含文档+PPT+源码等]计算机毕业设计基于SpringBoot的体育馆场地预约赛事管理系统的设计

文章目录 **软件开发环境及开发工具&#xff1a;****功能介绍&#xff1a;****论文截图&#xff1a;****数据库&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及…

嵌入式酒精壁炉:时尚生活的新宠

在这个注重品质与生活方式的时代&#xff0c;我们对于家居生活的要求早已不仅仅停留在实用性上。越来越多的人希望能够在家中营造一种时尚、温馨的氛围&#xff0c;而酒精壁炉恰好成为了这个潮流生活的代表。 如今&#xff0c;品质生活已经成为时尚的代名词。酒精壁炉以其精湛的…

图像分类系列(二) VGGNet学习详细记录

经典神经网络论文超详细解读&#xff08;二&#xff09;——VGGNet学习笔记&#xff08;翻译&#xff0b;精读&#xff09; 前言 上一篇我们介绍了经典神经网络的开山力作——AlexNet&#xff1a;经典神经网络论文超详细解读&#xff08;一&#xff09;——AlexNet学习笔记&a…

解密.locked1勒索病毒:专家级策略保护您的数据免受勒索攻击

导言&#xff1a; 在当今数字化的世界中&#xff0c;勒索病毒的威胁日益严峻。.locked1 勒索病毒作为其中的一种&#xff0c;采用高级的加密算法对用户文件进行加密&#xff0c;要求支付赎金以获取解密密钥。本文91数据恢复将介绍如何面对.locked1 勒索病毒&#xff0c;有效恢…

Python 3.12 版本有什么变化?

在前不久&#xff0c;python 3.12 正式发布了&#xff0c;那到底更新了哪些内容呢&#xff1f;一起来看看。 # 改善报错信息 来自官方标准库的模块现在可以在报NameError时提示问题原因&#xff0c;比如 >>> sys.version_info Traceback (most recent call last):Fi…

SpringBoot2—基础篇

目录 快速上手SpringBoot • SpringBoot入门程序开发 基于Idea创建SpringBoot工程&#xff08;一&#xff09; 基于官网创建SpringBoot工程&#xff08;二&#xff09; 基于阿里云创建SpringBoot工程&#xff08;三&#xff09; 手工创建Maven工程修改为SpringBoot工程&…

线程状态及线程之间通信

线程状态概述 当线程被创建并启动以后&#xff0c;它既不是一启动就进入了执行状态&#xff0c;也不是一直处于执行状态。在线程的生命周期中&#xff0c; 有几种状态呢&#xff1f;在 java.lang.Thread.State 这个枚举中给出了六种线程状态&#xff1a; 线程状态 导致状态发生…

Shopee活动名称怎么填写好?Shopee活动名称设置注意事项——站斧浏览器

虾皮活动名称的设定不仅是一个技巧性的问题&#xff0c;更是一门艺术。通过合理的活动名称设计&#xff0c;可以吸引更多的消费者参与活动&#xff0c;增加活动的曝光度和影响力。 shopee活动名称怎么填写好 简洁明了&#xff1a;活动名称应该尽量简洁明了&#xff0c;能够一…

北邮22级信通院数电:Verilog-FPGA(10)第十周实验 实现移位寄存器74LS595

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 二.管脚分配 三.实现过程讲解及效…

上机练习 8: DataFrame 综合练习

记录一下做的练习题 目录 1)自定义一个 Series 并命名为 s1&#xff0c;自定义索引值&#xff0c;采用随机数作为其中数据尝试使用 s1.sum(计算其中所有数据的和,使用 s.mean(计算其中所有数据的平均值。 2)创建一个形状为4*6的 DataFrame 并命名为 df1,并指定行索引为[“a”…

多媒体领域顶会ACM MM 2023 获奖论文一览

ACM 国际多媒体会议是计算机科学领域中多媒体领域的顶级会议&#xff0c;属于CCF A类。今年的ACM MM 2023 已于2023年10月29日至11月2日在加拿大渥太华举行。 ACM MM会议专注于推动多媒体研究和应用&#xff0c;其研究领域广泛涉及触觉、视频、VR/AR、音频、语音、音乐、传感器…

23届计科,想找Java开发之类,真的是很难吗?

23届计科&#xff0c;想找Java开发之类&#xff0c;真的是很难吗&#xff1f; 你的投递信息(投递多少家&#xff0c;如何跟hr打招呼&#xff0c;已读不回如何应对等)都亮- -下才能知道问题出在 哪。最近很多小伙伴找我&#xff0c;说想要一些Java的资料&#xff0c;然后我根据…

asp.net在线考试系统+sqlserver数据库

asp.net在线考试系统sqlserver数据库主要技术&#xff1a; 基于asp.net架构和sql server数据库 功能模块&#xff1a; 首页 登陆 用户角色 管理员&#xff08;对老师和学生用户的增删改查&#xff09;&#xff0c;老师&#xff08;题库管理 选择题添加 选择题查询 判断题添加…

电商野路子:非标品中转仓项目

相信很多人之前都做过拼多多电商&#xff0c;抖音直播电商&#xff0c;淘宝虚拟电商&#xff0c;也做过淘宝传统电商&#xff0c;在童话看来&#xff0c;这些平台都已严重内卷&#xff0c;已经不再适合普通人进场了。凭你一没经验&#xff0c;二没背景&#xff0c;三没资源&…