论文导读 | 支持事务与图分析的图存储系统

news2024/11/16 1:55:49

事务系统保证了系统的数据一致性,确保事务更新的原子性或是不同事务之间的数据隔离性等在多线程并发环境下所必不可少的ACID特性。而在今天快速变化的商业环境下,诸如物流和供应链,金融风控和欺诈检测等场景都需要图分析系统提供对数据动态更新和新鲜度的更高要求。因此,在图分析系统中支持事务机制至关重要。本文将介绍三篇相关论文Livegraph,Teseo与Sortledton。

图片

图片

图片

背景介绍

图分析系统通常存储下图的拓扑结构以及必要的属性,并支持在存储图上高效执行各类图算法,例如单源最短路(Single source shortest path,SSSP)和PageRank(PR)算法。在大多数原生的图存储系统中,拓扑结构通常采用下图所示的两种方法:1.稀疏矩阵行压缩(compressed sparse row,CSR),2.邻接表。

图片

CSR通过将所有顶点的所有邻域共同存储连续的内存位置,形成一个紧凑的结构,支持快速的读取,但需要承担高额的修改代价。邻接表的各个顶点邻域分别存储,读取上由于邻域不存储在一起需要若干次指针查找会逊色于CSR结构。

事务方面,目前的主流系统都采取的多版本并发控制(multiple version concurrency control,MVCC)来实现。MVCC的主要思想是存储数据的多个版本,记录这些版本创建和无效的时间戳。而各个事务可以根据自己的时间戳读取自己需要的版本数据,以此避免读写冲突。根据不同时间戳限制可以轻松实现读已提交、快照隔离等不同隔离等级,并可以引入经典的两阶段锁策略实现可串行化隔离等级。

本文介绍的三篇论文旨在将图分析与事务两种操作结合在一个图存储系统中从而实现高效且支持并发的图分析操作。他们在事务方面皆采用了MVCC方案,并分别构建了自己的图存储数据结构。

设计思路

本部分将介绍三篇论文的数据结构的设计思路。

LiveGraph:

图分析的基本操作是大量的邻接表扫描,包含一次查找顶点邻域的seek和一次扫描邻域的scan两种操作。目前的主流图存储结构中,通常分为以neo4j为代表的链表形式、为了适应磁盘交换数据而设计的LSM-Tree(Log Structured Merge Tree)和B+Tree及上文描述过的CSR形式。这些结构在两类操作(seek和scan)上的效率各不相同。CSR以更新代价为代价达到最好的性能。

图片

这之中,LiveGraph提出的新数据结构:事务型边日志(TEL)在连续TEL在连续内存上结合多版本,能够达到类似CSR的常数级seek并支持连续扫描邻域。下表也能够体现TEL相对于LSMT、B+Tree和链表的优势。

图片

Teseo:

在LiveGraph的基础上,Teseo认为不仅要考虑某个点邻域的寻址与扫描问题,也要考虑扫描不同邻域时的时间消耗。Teseo总结图分析算法如下图,认为扫描所有邻域的图分析算法有两类:一是顺序扫描所有邻域,二是随机访问所有邻域。前者典型如PageRank,后者典型如SSSP。而类似LiveGraph这种邻接表的形式无法很好处理不同邻域的扫描。

图片

Sortledton:

Sortledton设计了相关的实验,将同一个顶点的邻域存储在块大小超过256的链状块结构即可达到与存储在连续内存空间相近的效率。同时,Teseo中针对扫描所有顶点邻域的优化并不是必要的。最后,Sortledton总结了包括LiveGraph和Teseo在内的多个动态图分析结构,认为动态图结合事务系统需要提供三类操作:支持并发的事务操作,用于图分析的扫描操作和用于图模式匹配的快速交集(要求数据结构有序)操作。

图片

数据结构与事务机制

本部分介绍三篇论文具体的数据结构与事务机制设计。

LiveGraph

图片

上图展示了LiveGraph数据结构的基本布局。LiveGraph基于属性图建模,每条边具有多种属性,并且有且仅有一个标签(Label)。点的相关信息都存储在Vertex Block(VB)里,而同一个点的同一类标签的出边都存放在一个TEL结构里。LiveGraph利用全局的点和边索引来快速定位需要操作的VB和TEL。

TEL内部的结构如下图所示,除了开头固定长度的元数据外,相关边与对应属性在一个倍增的动态扩容数组中分别从两头往中间增长。最新的数据被存储在最中间。这种布局保证了扫描一个邻域时是顺序访问内存的。此外,LiveGraph在基础数据结构中就实现了多版本存储:每个边在被删除或更新时,并不是直接在动态数组中删除该边及属性,而是修改该边的无效时间戳Invalidation TS,存储下这条边的历史数据。

为了支持这种多版本的存储,新边的插入操作不需要改变,但原有边的更新操作需要修改旧版本的无效时间戳。为了快速判断边操作是插入还是更新,LiveGraph在每个TEL的元数据出添加了一个Bloom filter加速判断。由于TEL的边是按照时间顺序存储的,因此单边查询可能需要scan整个TEL结构。

图片

事务方面,LiveGraph实现了快照隔离。在全局有一个主线程管理事务,各个分线程执行事务,同时存在一个全局读时间戳GRE与写时间戳GWE。每个顶点拥有一个futex,在快照隔离下读写操作不互斥,事务的写操作在提交前不会被其他事务所读取,而写写操作则通过锁进行互斥。每个TEL额外维护一个最新提交时间CT与日志大小LS并在事务提交时更新,日志大小LS可以防止其他线程读取到未提交的数据。为了防止死锁,LiveGraph将超时的事务进行回滚,并使用批量提交的方法提高吞吐率。

具体而言,读写事务的操作分为以下三个阶段:

1.事务开启:事务读时间戳TRE设为GRE,写操作获取写锁后,更新私人版本。该私人版本由于日志大小LS未更新因此不会被读取。

2.事务持久化:事务提交前,交由主线程执行组提交。主线程令GWE+1。将日志同步到磁盘后。通知各线程执行提交。

3.事务提交:修改CT与LS。释放写锁。修改日志时间戳。组提交完成后,通知主线程令GRE+1,使事务可见。

Teseo

首先介绍Teseo使用的数据结构之一PMA。

图片

如上图所示,PMA是带有空隙的数组,将之分成若干segment。插入时优先插入segment中的空隙,若segment满时则联合周围若干segment执行rebalance,元素过多时可能执行数组的倍增。每次更新的最差效率为O(logN)^2,均匀分布的均摊效率是O(logN)。参数的设置可以保证rebalance段的填充率约为75%,而整体数组的填充率为50%。

图片

Teseo的设计灵感从B+Tree出发。B+Tree的问题在于:B+tree的叶子较小(4KB),大度数的邻域scan将频繁跨越叶子。并且小度数的邻域scan将近似对数效率的点查找。因此Teseo提出了Fat-tree,如上图所示:1. 增大叶子大小至MB级别 2. 添加hash map作为secondary index加速点查找。

但简单地扩大叶子会提高更新的代价。因此Teseo将叶子的数据结构组织为稀疏数组。每个Segment具有一对fence key;叶子节点以min key为键,构建ART索引方便快速查找叶子。当稀疏数组需要expand时,执行split,保证叶子大小在X/2~X之间。删除时不执行rebalance,而是在必要时进行叶子间的merge。

Teseo将segment分为读优化段ROS和写优化段WOS,如下图所示。初始段模式为ROS,在segment的两边存储数据。插入时需要挪动数据。为了防止更新偏斜的最差情况,段满时以延迟D执行rebalance。为此需要一个机制存储多余的数据:WOS段模式。WOS段模式利用段外的buffer和段内的索引存储数据,数据为<src,dst>,索引为ART tree。

图片

为了支持事务的并发,每个segment具有一个hybrid latch。携带一个版本标记的读写锁,读数据时乐观地可以选择不加读锁,而通过对比版本确保无人修改数据。为了防止死锁,Teseo的只读事务会获得传统的读锁存器。而读写事务的读操作则只能获取乐观模式的锁存器。由于Fat-Tree需要执行若干叶子中segment的rebalance,需要计算segment的长度。因此叶子节点还需要添加一个锁存器。二级索引使用的哈希表使用了无锁实现,同样可以保证线程安全。同时,在每个存储数组后面添加一个版本区域,以版本链的形式将数据的所有版本串联在一起,如下图所示。Teseo的事务执行逻辑基本与Hyper类似。

图片

Sortledton

图片

由于不需要优化所有邻域的访问模式,Sortledton采取邻接表的形式,以简化结构。如背景介绍中描述的,邻接表主要分为两个部分:点到边集的映射与某个点的邻边有序集。Sortledton的点边映射采用的两级数据如上图所示,第一级存储第二级数组的指针,每次扩容时新增一个大小翻倍的第二级数组。

而邻边有序集方面,根据设计思想一节中介绍的指导思想,不需要将邻边有序集都存储在连续物理内存,可以用块大小较大的链式块达到近似的处理速度。因此Sortledton选择松散链表,支持对数级别的查询更新的同时,维护边的有序性并避免类似B+ Tree的rebalance操作。

为了实现多版本存储,Sortledton在每个边维护的信息中加入一个版本链指针,并实现了一个传统的版本链维护。Sortledton的整体存储架构如下图所示,包括一个二级数组实现的动态索引,基于松散链表存储的每个点邻域与对应的版本链存储。

图片

事务方面,Sortledton专注于优化具有已知读写集的读写事务和只读事务,认为这两种类型是图分析事务中最主要的事务。针对具有已知读写集的读写事务而言,事务的操作按照顺序主要分为:由于写集已知,因此可以先获取所有对应数据的锁,之后读取最新版本数据。最后获取commit时间戳,并在完成写操作后释放锁。而针对只读事务,则先获取read时间戳,并在需要读取数据时加读锁,读取数据后释放读锁。

实验

由于Sortledton的实验对比对象包括LiveGraph和Teseo,因此本文直接介绍Sortledton进行的实验。本实验采用的数据集是由LDBC数据生成器生成的图数据。

第一部分的测试比较插入的性能,对比的对象分别为Teseo,LiveGraph,GraphOne,Llama以及Stringer。插入的同时要求先查询该边是否存在。下图中存在巨大性能差异时主要由于存在性检测导致的:Teseo和Sortledton的边集有序,因此可以快速查询存在性;GraphOne不支持存在性查询。因此它们与另外三个系统存在较大的性能差异。

图片

第二部分的实验是针对图算法的实验,主要比较的图算法包括局部集聚系数LCC、单源最短路SSSP、广度优先搜索BFS、弱连通分量WCC、基于标签传播的社区检测CDLP和PageRank。并且以CSR作为baseline。可以看出Teseo和Sortledton在各算法表现中较好,其中Sortledton更胜一筹。值得注意的是,LCC由于需要执行交集操作,只有维护有序集的Teseo和Sortledton才能在有效时间内执行。

图片

第三部分的实验是针对事务系统的实验,因此只有对支持事务的Teseo和LiveGraph系统的对比,其中Teseo由于在Sortledton进行实验期间存在bug,因此只有与LiveGraph的对比。可以看出,在线程数较少时,Sortledton的性比对LiveGraph有较大的优势,与第二部分的实验一致。但线程数较多时,两者在PR上的性能差距不大。这是因为LiveGraph的多版本是顺序存储的,而Sortledton需要遵循版本链,存在不连续的内存空间。

图片

总结

本文介绍的三个系统在使用类CSR结构或邻接表的情况下,LiveGraph、Teseo、Sortledton有效的融合了事务系统和图分析系统,做到支持并发动态图分析。三篇论文为我们提供了设计针对图分析有效的数据结构,并设计了配套的事务系统的思路。

图片

图片

欢迎关注北京大学王选计算机研究所数据管理实验室微信公众号“图谱学苑“
实验室官网:https://mod.wict.pku.edu.cn/
微信社区群:请回复“社区”获取

实验室开源产品图数据库gStore:
gStore官网:https://www.gstore.cn/
GitHub:https://github.com/pkumod/gStore
Gitee:https://gitee.com/PKUMOD/gStore

图片

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

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

相关文章

Node.js在Python中的应用实例解析

随着互联网的发展&#xff0c;数据爬取成为了获取信息的重要手段。本文将以豆瓣网为案例&#xff0c;通过技术问答的方式&#xff0c;介绍如何使用Node.js在Python中实现数据爬取&#xff0c;并提供详细的实现代码过程。 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境…

SEAL:RLWE-BFV 开源算法库

参考文献&#xff1a; GitHub - microsoft/SEAL: Microsoft SEAL is an easy-to-use and powerful homomorphic encryption library.[HS13] Halevi S, Shoup V. Design and implementation of a homomorphic-encryption library[J]. IBM Research (Manuscript), 2013, 6(12-15…

UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

在UML类图中&#xff0c;常见的有以下几种关系: 泛化&#xff08;Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#xff0c;组合(Composition)&#x…

【python零基础入门学习】python进阶篇之OOP - 面向对象的程序设计

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

MS5248数模转换器可pin对pin兼容AD5648

MS5228/5248/5268 是一款 12/14/16bit 八通道输出的电压型 DAC&#xff0c;内部集成上电复位电路、可选内部基准、接口采用四线串口模式&#xff0c;最高工作频率可以到 40MHz&#xff0c;可以兼容 SPI、QSPI、DSP 接口和 Microwire 串口。可pin对pin兼容AD5648。输出接到一个 …

潮玩IP助力环境保护,泡泡玛特发布行业首款碳中和产品

在今年的2023上海PTS国际潮流玩具展上&#xff0c;泡泡玛特正式发布了首款“碳中和”潮玩产品DIMOO X蒙新河狸手办&#xff08;下简称DIMOO河狸&#xff09;&#xff0c;通过环保主题与流行文化的联合&#xff0c;让年轻人知道野生动物保护有多种方式&#xff0c;同时以创新的设…

Crypto(3)NewStarCTF 2023 公开赛道 WEEK2|Crypto-不止一个pi

题目代码 from flag import flag from Crypto.Util.number import * import gmpy2 p getPrime(1024) #这行生成一个大约1024位长度的随机素数&#xff0c;并将其赋给变量p。 q getPrime(1024) #类似地&#xff0c;这行生成另一个大约1024位长度的随机素数&#xff0c;并将其…

Fortinet详解如何量化网安价值,把握网安态势

网络安全价值量化是企业准确把握自身网络安全态势的前提&#xff0c;也是网络安全管理人员持续推动工作的有力支撑。网络安全行业发展迅速&#xff0c;其价值量化也在不断地演进&#xff0c;如何进行量化则一直都是企业和网络安全管理人员的挑战。近期&#xff0c;Fortinet 委托…

【视觉算法系列2】在自定义数据集上训练 YOLO NAS(上篇)

提示&#xff1a;免费获取本文涉及的完整代码与数据集&#xff0c;请添加微信peaeci122 YOLO-NAS是目前最新的YOLO目标检测模型&#xff0c;它在准确性方面击败了所有其他 YOLO 模型。与之前的 YOLO 模型相比&#xff0c;预训练的 YOLO-NAS 模型能够以更高的准确度检测更多目标…

【三】kubernetes kuboard部署分布式系统

#服务器 #部署 #云原生 #k8s 目录 一、前言二、搭建docker私有仓库三、系统搭建1、NFS部署1)部署nfs server &#xff08;192.168.16.200&#xff09;2)部署nfs client &#xff08;全部节点&#xff09;3)在Kuboard中创建 NFS 存储类 2、创建命名空间3、添加docker密文4、创建…

Nginx 配置文件解读

一.配置文件解读 nginx配置文件主要分为四个部分&#xff1a; main{ #&#xff08;全局设置&#xff09;http{ #服务器配置upstream{} #&#xff08;负载均衡服务器设置&#xff09;server{ #&#xff08;主机设置&#xff1a;主要用于指定主机和端口&#xff09;location{} …

Flink学习之旅:(三)Flink源算子(数据源)

1.Flink数据源 Flink可以从各种数据源获取数据&#xff0c;然后构建DataStream 进行处理转换。source就是整个数据处理程序的输入端。 数据集合数据文件Socket数据kafka数据自定义Source 2.案例 2.1.从集合中获取数据 创建 FlinkSource_List 类&#xff0c;再创建个 Student 类…

5256C 5G终端综合测试仪

01 5256C 5G终端综合测试仪 产品综述&#xff1a; 5256C 5G终端综合测试仪主要用于5G终端、基带芯片的研发、生产、校准、检测、认证和教学等领域。该仪表具备5G信号发送功能、5G信号功率特性、解调特性和频谱特性分析功能&#xff0c;支持5G终端的产线高速校准及终端发射机…

Dev-C++ 软件安装教程

Dev-C 软件安装包https://download.csdn.net/download/W_Fe5/88446511&#xff08;软件包下载后&#xff0c;右键解压&#xff09; 一、打开文件夹&#xff0c;双击“Dev-C” 二、软件安装&#xff0c;点击“OK” 三、点击“I Agree” 四、点击“Next” 五、更改安装目录&…

虚拟机ubantu系统突然重启失去网络

1.进入 root用户 cd /var/lib/NetworkManager然后查看网络服务状态 如果网络状态和我一样不可用 ,就先停止网络服务 service ModemManager stop#删除状态rm networker.stateservice ModemManager start

基于Pytorch的CNN手写数字识别

作为深度学习小白&#xff0c;我想把自己学习的过程记录下来&#xff0c;作为实践部分&#xff0c;我会写一个通用框架&#xff0c;并会不断完善这个框架&#xff0c;作为自己的入门学习。因此略过环境搭建和基础知识的步骤&#xff0c;直接从代码实战开始。 一.下载数据集并加…

【遮天】最新预告,叶凡一怒报仇,导演再删减人物,还暴露一个严重问题

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析遮天国漫资讯。 《遮天》动漫第30集预告已出&#xff0c;叶凡被挟持进入荒古禁地&#xff01;这一集看下来&#xff0c;导演又删减人物了&#xff0c;还暴露一个问题。 在预告中&#xff0c;叶凡已经被姬家和姜家的人带往…

【C++ 学习 ㉙】- 详解 C++11 的 constexpr 和 decltype 关键字

目录 一、constexpr 关键字 1.1 - constexpr 修饰普通变量 1.2 - constexpr 修饰函数 1.3 - constexpr 修饰类的构造函数 1.4 - constexpr 和 const 的区别 二、decltype 关键字 2.1 - 推导规则 2.2 - 实际应用 一、constexpr 关键字 constexpr 是 C11 新引入的关键字…

Spring Boot学习笔记(1)

Spring Boot学习笔记&#xff08;1&#xff09; 1.环境1.win2.mac3. IDEA 2.知识点1.Record类2.Switch开关表达式3. var和sealed4.springboot5.启用lombok 学习资料&#xff1a; 官网&#xff0c; 手册&#xff0c; 视频。 1.环境 1.win 1.下载vscode 2.安装jdk&#xff0…

求助C语言大佬:C语言的main函数参数问题

最近在敲代码的过程中&#xff0c;突发奇想&#xff0c;产生了一个疑问&#xff1a; 为什么main函数可以任由我们定义&#xff1a;可以接收一个参数、两个参数、三个参数都接接收&#xff0c;或者可以不接收&#xff1f;这是如何实现的 int main(){retrun 0; } int main (int…