Tugraph的设计和源码初步解析

1. Tugraph

Tugraph是一款开源的性能优秀的图数据库,该图数据库使用多版本的B+Tree作为数据的存储引擎,同时设置了点边数据在这个存储引擎上的布局(主要考虑数据的局部性),从而达到高性能查询的目的。本文主要从Tugraph使用的存储引擎和Tugraph的设计角度进行一些分析。TuGraph的源码仓库:GitHub - TuGraph-family/tugraph-db: TuGraph is a high performance graph database.

2. LMDB

2.1 LMDB的特点:

优点:

  • 基于B+树的key/value存储
  • 支持事务(ACID),隔离界别为Serializable 
  • 支持多版本控制,读操作不会阻塞写操作
  • 使用memory-mapped映射文件,不需要调整cache的参数,冲突重启不需要恢复数据
  • 使用CacheLine对齐的数据结构,对CPU的缓存友好
  • 支持并发操作,支持多进程或者多线程,Writer不会阻塞Reader,同样Reader不会阻塞Writer
  • 在多CPU机器上读操作可以实现真正的线性扩展,没有死锁的问题
  • 完全隔离的多版本并发(实现中两个版本),Serializable的隔离等级,可以实现事务的嵌套(Tugraph没有实现事务的嵌套)
  • 可以批量写
  • 使用Copy-on-Write,数据不会被覆盖,只会Append写入,两个版本保证旧数据会空间会被回收复用;
  • 无需WAL,DB崩溃后无需恢复,没有commit的数据视为无效数据无需恢复
  • 使用单级存储(Single-Level Store)
  • 读操作直接饮用MMAP指针,没有数据拷贝开销
  • 写操作直接写入MMAP映射到磁盘,没有buffer,也不需要buff的调参。依赖于OS的pageCache,在应用层没有cache的浪费

缺点:

  • 任意时刻只能一个线程写数据
  • 对于长时间事务来说,多版本树可能会蜕变成append-only树,导致写入后数据无限增长;
  • 没有compaction机制,导致数据不能做TTL的回收
  • 使用操作系统来管理内存,数据库的性能会收到系统的影响比较大
  • 使用mmap,频繁缺页产生中断,会对性能产生影响

2.2 LMDB的实现原理

Append only tree:

如下图有个三层结构的B+Tree结构

 他在硬盘上的存储结果如下所示:

每个方框的是一个page的大小,由于磁盘测存储是一维的,所以这里会按照page Flat成一位的存储,Mata存在在文件的最尾部,他记录的root的pageID,从Meta中就可以将整棵树遍历,一般Meta在内存中;当我们修改Leaf8中的数据的时候,会有如下的变化:

由于我们采用COW的方式,因此并不会in-place的修改leaf8上的数据,而是将leaf8 copy到一个新的page,由于file中增加的新的page,改变了树的结构,因为这个修改会将leaf8的父节点,一直到根节点复制一份。新的父节点指向新的叶子结点(这里是leaf12),对于没有修改的leaf还保持指向不变。此时会有两个版本的数据同时存在,如果此时有读tranaction指向leaf8,他读到的数据还是之前的老版本数据,一直到其tranction结束;当修改leaf12的事务完成写的时候,整个修改在磁盘上的形式如下所示:

可以看到,修改一个page的数据需要增加4个page的数据append到文件的尾部,会带来一定的写放大,以及磁盘空间的浪费。但是这种顺序的写入相比随机in-place的写入效率会高很多,并且这种写入不需要事务日志,因为数据本文件本身就是日志;这种Append-Only的形式带来的问题就是旧版本数据的会积累的越来越多,文件大小会无限的增加上去,为了解决这个问题,LMDB采用每个root维护两个B+Tree的方式;其中一个存储用户的数据,另一个存储给定的事务中空闲的pageID 列表,这样就的一些老的page可以被重复利用,从而保证数据库无限制的增加,同时也减少了Compaction的过程(注意这里是有条件的,旧的page不被其他事务引用的情况下才会进行服用旧的闲置的page);

LMDB的实现方式

下面以进行四个transaction进行数据写入为例:

 可以看到LMDB的数据数据没有像Append-only Tree那样数据无尽的增长下去,这主要归功于lmdb的多版本的功能(目前只有两个版本),旧版本数据不在被读者使用的时候,就会释放空间,义工后续的数据写入;

3. Tugraph设计解析

Tugraph的数据是在lmdb的基础上使用page为单位存储点以及改点的临边的数据,这样可以保证能够快速读取某点以及某点所以临边的数据;

Tugraph的设计:

 如图所示,tugraph支持多图空间,用GraphManager来管理多个图,每个图里面分为schema模块,graph模块,索引管理模块,插件管理模块,以及全文索引管理模块等组成。其中schema模块主要管理数据的元信息,而真正的数据存储在graph中,这里面每个模块管理的数据都在对应到lmdb的一个表中。而tugraph的点边数据组成如下所示:

 4. 总结

        Tugraph采用lmdb作为存储引擎,也就具备了lmdb的优缺点,具有优秀的查询性能,但是尽管采用多版本的append-Only Tree和COW技术,使得在写入数据的时候具有明显的写放大行为;同时由于没有compaction的行为,使得Tugraph的数据只能不断的增长;

5. 参考文献

  1. how the append-only btree works
  2. LMDB API查询
  3. LMDB benchmark
  4. http://www.lmdb.tech/media/20141120-BuildStuff-Lightning.pdf  OpenLDAP Project LMDB
  5. Symas LMDB Tech Info | Symas
  6. https://arxiv.org/pdf/1910.05773.pdf  LiveGraph的原理介绍
  7. https://www.usenix.org/system/files/conference/osdi16/osdi16-zhu.pdf Gemini: A Computation-Centric Distributed Graph Processing System
  8. https://www.usenix.org/system/files/conference/fast15/fast15-paper-zheng.pdf
  9. https://www.usenix.org/system/files/conference/osdi12/osdi12-final-126.pdf
  10. MMap: Fast Billion-Scale Graph Computation on a PC via Memory Mapping - PMC  MMap: Fast Billion-Scale Graph Computation on a PC via Memory Mapping

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

研发工程师玩转Kubernetes——自动扩缩容

在《研发工程师玩转Kubernetes——使用Deployment进行多副本维护》一文中,我们通过Deployment实现了多副本维护——即维持在一个确定数量的副本个数。而在现实场景中,我们往往需要根据服务的压力,采用水平(横向)扩容的…

Springboot +spring security,前后端分离时的security处理方案(二)

一.简介 在前后端分离这样的开发模式下,前后端的交互都是通过 JSON 来进行数据传递的,无论登录成功还是失败,都不会有服务端跳转或者客户端跳转之类的操作。 也就是说无论登录成功还是失败,服务端都会返回一段登录成功或失败的 …

使用【Python+Appium】实现自动化测试

一、环境准备 1.脚本语言:Python3.x IDE:安装Pycharm 2.安装Java JDK 、Android SDK 3.adb环境,path添加E:\Software\Android_SDK\platform-tools 4.安装Appium for windows,官网地址 Redirecting 点击下载按钮会到GitHub的…

解决dpdk reserve的内存返回的虚拟地址和iova地址一样的问题

1. 背景: 在ubuntu20.04上用dpdk API: rte_memzone_reserve_aligned("L1L2_PCIE_MEMORY", 1.5*1024*1024*1024, rte_socket_id(), RTE_MEMZONE_1GB|RTE_MEMZONE_IOVA_CONTIG, RTE_CACHE_LINE_SIZE); 分配1.5…

如何在 GNU Linux 上通过 Nvm 安装 Node 和 Npm?

Node.js 是一个流行的 JavaScript 运行时环境,用于开发服务器端和网络应用程序。它带有一个强大的软件包管理器 npm,可以方便地安装和管理 JavaScript 包和依赖项。在 GNU/Linux 系统上,使用 Nvm(Node Version Manager&#xff09…

Framework开发环境搭建

Framework开发环境搭建 开启Android Framework之旅,一步步记录自己学习过程。 硬件配置 RAM:最低16GB,建议32GB,有条件64GB,内存越高,编译时间越短ROM:最低400GB,代码250GB构建15…

Svn安装

目录 一. 软件环境 二. SVN服务端 1. yum安装svn 2. 查看安装的文件列表 3. 建立版本库 3.1 修改数据存储默认位置 3.2 使用svnadmin建立版本库 4. 配制 4.1 添加用户 4.2 配制读写权限 4.3 配制服务 5. 启动服务 5.1 停止服务 5.2 启动服务 5.3 拉取项目 三.…

Zookeeper集群 + Kafka集群

Zookeeper 概述 Zookeeper 定义 Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的…

CodeForces.1786A2.发牌.[中等][flg标识][数学规律][双色牌]

题目描述: 题目解读: 发牌问题,给两人发双色牌,同样还是 给a发1张,然后给b发2,3张; 给a发4,5张,给b发6,7张; 给a发8,9张&#xff…

《最新出炉》Python+Playwright自动化测试-2-playwright的API及其他知识

一.简介 上一篇我已经将PythonPlaywright的环境搭建好了,而且也简单的演示了一下三款浏览器的启动和关闭,是不是很简单啊。今天主要是把一篇的中的代码进行一次详细的注释,然后说一下playwright的API和其他相关知识点。那么首先将上一篇中的…

Spring Cloud面试题

组件 Spring Cloud Eureka:服务注册与发现 Spring Cloud Zuul:服务网关 Spring Cloud Ribbon:客户端负载均衡 Spring Cloud Feign:声明性的Web服务客户端 Spring Cloud Hystrix:断路器 Spring Cloud Config&#xff1…

[C++]octomap安装后测试

测试环境&#xff1a; vs2019 octomap1.9.6 release x64 代码&#xff1a; #include <octomap/octomap.h> #include <octomap/OcTree.h> using namespace std; using namespace octomap; void print_query_info(point3d query, OcTreeNode* node) { if (…

矿井水除氟,污水除氟的工艺分析

高矿化度的废水是指含有高浓度溶解性矿物质的废水&#xff0c;通常指的是含有高浓度钠、钙、镁、铁、铝、钾等离子的废水。这些离子通常来自于废水所处的环境、工业或生产过程中使用的原材料和化学品。高矿化度的废水通常具有高盐度、高电导率、高硬度等特征&#xff0c;对环境…

Vivado综合属性系列之十二 BLACK_BOX

目录 一、前言 二、BLACK_BOX ​2.1 属性说明 ​2.2 工程代码 ​2.3 结果 一、前言 ​在调试中&#xff0c;有时不需要知道一个模块或实例的具体实现&#xff0c;或者需要使其对外属于不可见&#xff0c;只知道它的输入输出&#xff0c;即像一个黑盒&#xff0c;此时可以对模…

港联证券|“面值退”增多凸显A股市场化进程良性态势

近日&#xff0c;多家陷入“1元退市”危机的公司纷纷发布风险提示公告称&#xff0c;公司股票存在可能因股价低于面值被终止上市的风险。据《经济参考报》记者不完全统计&#xff0c;今年以来&#xff0c;沪深两市已有10余只个股锁定“面值退”&#xff0c;其中多以披星戴帽公司…

Windows平台下用例图中包含(include)、扩展(extend)和泛化(generalization)介绍

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows平台下用例图中包含(include)、扩展(extend)和泛化(generalization&#xff09;介绍。 用例图是解决用户需求的图&#xff0c;画好用例图一定要理清用例之间的关系。用例之间有三种关系&…

什么是跳表

什么是跳表 跳表全称为跳跃列表&#xff0c;它允许快速查询&#xff0c;插入和删除一个有序连续元素的数据链表。跳跃列表的平均查找和插入时间复杂度都是O(logn)。快速查询是通过维护一个多层次的链表&#xff0c;且每一层链表中的元素是前一层链表元素的子集&#xff08;见右…

【Qt】QLocalSocket与QLocalServer问题:接收不到数据、只能收到第一条、数据不完整解决方案【2023.05.24】

简介 Qt很强大,但是Qt的帮助文档、API属实是让我们走不少弯路。QLocalSocket一个很简单的东西,我仅想用来实现一个简单的本地进程通信,就遇到了:客户端循环发送数据,服务端只能接收到一条、接收到数据不完整等奇奇怪怪的现象。 最郁闷的是,网上很多教程说的都是错的😒。…

Spring Authorization Server 系列(三)code换取token

code换取token 概述客户端认证方式换取结果 概述 在获取到code后&#xff0c;就可以使用code换取token了&#xff0c;但在换取token这一步还会对客户端进行一些校验&#xff0c;而这也支持不同的方式&#xff0c;一起来看看。 客户端认证方式 JwtClientAssertionAuthenticati…

期末复习总结【MySQL】聚合查询 + 多表联合查询(重点)

文章目录 前言一、聚合查询1, 聚合函数2, 聚合函数使用示例3, GROUP BY 子句4, HAVING 子句 二、联合查询(重点)1, 笛卡尔积2, 内连接2.1, 示例12.2, 示例22.3, 示例3 3, 外连接4, 自连接 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#…