Nebula Storage 2.0 存储格式
随着 2.0 各版本的陆续发布,Nebula Graph 迎来了一系列的改动,在存储方面,影响最大的改动就是底层编码格式进行了修改。Nebula Graph 的底层存储是基于 KV 保存在 RocksDB 中,本文将介绍新老编码格式的差异,以及为什么要修改存储格式等一系列问题。
1.0 版本的格式
我们先简单回顾下 1.0 版本的编码格式,不熟悉的可以参考这篇博客《Nebula 架构剖析系列(一)图数据库的存储设计》。由于在 1.0 版本中,点的 ID 只能够用整型来表示,所以底层所有 VertexID 都是以 int64 来保存的。
- 点的格式
- 边的格式
给定任何一个 VertexID,经过 hash,可以得到对应的 PartID,因此对于一个点和这个点的所有边(边用起点计算 hash),都会映射到同一个分片中。需要指出的是,在 1.0 版本中,点和边的第一个字节的 Type 是相同的。也就是说,对于一个点而言,它的所有 tag 并没有在物理上连续保存,比如可能是如下保存的。对于这个 src 这个点的三个 tag(tag1 tag2 tag3),实际上可能会被其他边隔开。
这个格式能够满足 1.0 绝大多数接口的需要,比如 fetch
和 go
都只需要指定对应前缀,就能获取对应数据。
2.0 版本的格式
在 GA 之前发布的版本,底层存储格式其实和 1.0 是基本相同的。如果 VertexID 是整型,和 1.0 格式完全一致。而如果 VertexID 类型支持 string,则从占用 8 个字节的 int64 改成了固定长度的 FIXED_STRING
,长度需要用户在 create space
时候指定长度。对于不足的长度系统自动使用 \0
补齐,而超过指定长度的 VertexID 会直接报错。
在 GA 版本中,我们对底层存储格式进行了若干改动,因此这次版本升级时需要通过升级工具,将原有格式的数据转换为新格式的数据。如下是在 2.0 GA 版本中采用的存储格式。
2.0 版本存储格式
- 点的格式
- 边的格式
和 1.0 存储格式对比
其中有几个比较大的改动:
- VertexID 的长度如前文所说,从固定的 8 字节,修改为 n 个字节。VertexID 类型为整型时,n 为 8,VertexID 类型为 string 类型时,n 为指定长度。
- 点去掉了 1.0 的时间戳。边将 1.0 时间戳改为了一个字节的占位符。
- 对于点和边的第一个字节,不再使用同一个 Type,在物理上点和边进行了分离。
这些改动主要是基于以下几点进行考虑的:
- VertexID 改变主要是为了支持 string ID 同时兼容 1.0 版本 int ID。在 storage 中,把 VertexID 都处理为 bytes,只在返回结果时根据 space 的设置不同,返回相应类型的 VertexID。
为什么 string ID 要使用 FIXED_STRING ? 如果不使用固定长度,则无法使用前缀进行扫描。通过长度不足补齐,使得所有点之间和边之间的各个前缀长度相同,从而进行相应的前缀查询。
- 去掉时间戳主要是因为保存多版本数据会影响性能,另外一段时间内暂时不考虑做 MVCC 的相关工作。
在边里面还保留一个字节的占位符,主要是留给 TOSS(transaction on storage side)使用。主要用于标识一条边的出边和入边是否完整插入了,这里不详细介绍,后续会有其他文章进行详尽的分析。
- 点和边分离的好处主要是能够方便快速拿某个点的所有 tag(在Cypher 的
MATCH
语句中大量使用)。如果按原先同一Type + VertexID
前缀扫描,由于点边可能掺杂在一起,会极大影响性能。而 Type 分离之后,按VertexType + VertexID
前缀扫描,可以快速获取所有 tag。
在 1.0 版本中,由于没有取某个点的所有 tag 的需求,因此点和边可以按同一个前缀保存。不过在代码层面,还是有不小影响,例如 fetch 接口在 1.0 是按 VertexID 的前缀去扫描的,对于超级大点来说取 tag 性能比较差。另外如果使用 storage 提供的 scan 接口,想要获取全图的所有点,实际是扫描了整个 RocksDB。
除了点和边的格式相关改动之外,索引的格式其实也有所改变。
一方面是 2.0 支持 NULL
后,索引也需要能够表示对应的语义。另一方面是在 1.0 的版本中,对于索引中 string 的字段的处理,实际是按变长 string 处理。因此在 LOOKUP
语句中只要使用了带 string 字段的索引,就只能使用等值查询。而在 2.0 的版本中,索引的 string 字段和数据中的 VertexID 一样,使用固定长度的 FIXED_STRING,LOOKUP
语句中带 string 字段的索引能够使用范围查询,例如 LOOKUP ON index1 WHERE col > "aaa"
。有关索引部分的功能和修改,后续也会再有其他文章介绍。
以上,为本次 Nebula Storage 2.0 存储格式讲解。
喜欢这篇文章?来来来,给我们的 GitHub 点个 star 表鼓励啦~~ ♂️♀️ [手动跪谢]
交流图数据库技术?交个朋友,Nebula Graph 官方小助手微信:NebulaGraphbot 拉你进交流群~~
推荐阅读
Nebula Storage 2.0 存储格式的更多相关文章
- 初识分布式图数据库 Nebula Graph 2.0 Query Engine
摘要:本文主要介绍 Query 层的整体结构,并通过一条 nGQL 语句来介绍其通过 Query 层的四个主要模块的流程. 一.概述 分布式图数据库 Nebula Graph 2.0 版本相比 1.0 ...
- Nebula 2.5.0安装过程及遇到的坑
2021年8月23日,Nebula 发布了最新版本:2.5.0,正好赶上新环境部署,记录一下安装过程及遇到的坑: 一.准备工作 以下安装使用nebula用户,搭建集群模式,一共三台机器:192.168 ...
- MediaPlayer: Couldn't open /storage/emulated/0/kgmusic/download/独家记忆.mp3: java.io.FileNotFoundExcept
写了一个音乐播放器,播放的时候,会出现这样的问题:比如说我点击第三首歌曲,结果没有播放第三首歌曲,而直接播放了第四首歌曲.看了一下日志.发现报错:MediaPlayer: Couldn't open ...
- android 7.0拍照问题file:///storage/emulated/0/photo.jpeg exposed beyond app through ClipData.Item.getUri
Android7.0调用相机时出现新的错误: android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exp ...
- 错误:java.io.FileNotFoundException: /storage/emulated/0/Documents/eclipse-inst-win64.exe
在Android服务的最佳实例中:https://www.cnblogs.com/hh8888-log/p/10300972.html,在最后运行的时候,点击Start Download按钮总是会报一 ...
- Nebula 架构剖析系列(一)图数据库的存储设计
摘要 在讨论某个数据库时,存储 ( Storage ) 和计算 ( Query Engine ) 通常是讨论的热点,也是爱好者们了解某个数据库不可或缺的部分.每个数据库都有其独有的存储.计算方式,今天 ...
- Neo4j 导入 Nebula Graph 的实践总结
摘要: 主要介绍如何通过官方 ETL 工具 Exchange 将业务线上数据从 Neo4j 直接导入到 Nebula Graph 以及在导入过程中遇到的问题和优化方法. 本文首发于 Nebula 论坛 ...
- 图计算 on nLive:Nebula 的图计算实践
本文首发于 Nebula Graph Community 公众号 在 #图计算 on nLive# 直播活动中,来自 Nebula 研发团队的 nebula-plato 维护者郝彤和 nebula-a ...
- Spark1.0.x入门指南
1 节点说明 IP Role 192.168.1.111 ActiveNameNode 192.168.1.112 StandbyNameNode,Master,Worker 192.168.1. ...
随机推荐
- WSL2 VS Code远程开发准备
上一节我们在linux中创建了mvc项目,但是要是在linux中用命令行直接开发的话,就有些扯了. 我们可以使用VS Code进行远程开发,简单来说,就是在windows中打开VS Code,打开Li ...
- PowerShell随笔3 ---别名
上一篇提到了别名,这个有必要说一下,因为我们常常会遇到以下两种情况: 自己写脚本,想快速一些,使用命名 看别人的脚本,发现别人和你想的一样,用了别名,但是你忘记了这个别名是什么意思. 我们可以通过Ge ...
- 在.NET中体验GraphQL
前言 以前需要提供Web服务接口的时候,除了标准的WEBAPI形式,还考虑了OData.GraphQL等形式,虽然实现思路上有很大的区别,但对使用方来说,都是将查询的主动权让渡给了前端,让调用方能够更 ...
- VMware ESXi 开启嵌套虚拟化
VMware ESXi 默认不支持嵌套虚拟化功能,需要修改相关配置文件才能支持. 1.Esxi主机开启ssh,修改 /etc/vmware/config 配置文件,在配置文件后面加入如下配置:vhv. ...
- 一些CTF题目--20/9/3
1. 看源码 POST方法.Extract覆盖. 直接url ?参数不行,因为POST参数不在URL上,GET参数才在 Burpsuite抓包,改成 pass=1&thepassword_1 ...
- 网络流学习-Ford-Fulkerson
首先我们先解决最大流问题 什么是最大流问题呢 根据我的理解,有一个源点s,汇点t,s可以通过一个网络(雾)流向汇点t 但是每一条边都有他的最大传输容量限制,那么我们的任务是,如何分配流量使得..从s流 ...
- 作业day03吴童
小作业3 1. 求区间[100, 200]内10个随机整型数的最大值 1 import random 2 a = [] 3 for i in range(10): 4 n = random.randi ...
- STM32F107移植LWIP
STM32F107上移植LWIP2.0.3 因为最近需要在STM32F107上实现TCP/IP协议栈,所以网上查了一下,准备使用LWIP,虽然大多数用的是1.4.1版本但是官方说2系大版本修复了1.4 ...
- 前端水印方案 All In One
前端水印方案 All In One base64 用户名 图片水印 <div id="wm" style="pointer-events: none; width: ...
- 如何在没有显示器的情况下,查看 Raspberry Pi 3的 IP 信息(Raspberry Pi 3 ,IP Address)
1. 如何在没有显示器的情况下,查看 Raspberry Pi 3的 IP 信息(Raspberry Pi 3 ,IP Address) 1 IP Address Any device connect ...