图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)
图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)
大家好,我是洋仔,JanusGraph图解系列文章,实时更新~
图数据库文章总目录:
- 整理所有图相关文章,请移步(超链):图数据库系列-文章总目录
- 地址:https://liyangyang.blog.csdn.net/article/details/111031257
源码分析相关可查看github(码文不易,求个star~): https://github.com/YYDreamer/janusgraph
下述流程高清大图地址:https://www.processon.com/view/link/5f471b2e7d9c086b9903b629
版本:JanusGraph-0.5.2
转载文章请保留以下声明:
作者:洋仔聊编程
微信公众号:匠心Java
原文地址:https://liyangyang.blog.csdn.net/
正文
JanusGraph的数据导入过程主要分为三阶段:prepare(准备)、serialize(序列化)、commit(提交);不同阶段有不同的作用,如下:

下面我们分别从导入vertex节点和edge边两部分来分析写流程
建议依据源码同步看本文章,便于理解!
一:vertex数据写流程
下面vertex节点数据的导入,
prepare阶段
主要是依据当前给定的参数,组装出对应的vertex 或者 edge 对象;对象中包含对应的id、索引信息、属性信息和锁信息等;
过程中包含以下几种作用:
- 默认添加
vertex exist属性,值为true,标识当前节点是否存在 - 默认添加
label edge边,标识当前的节点 或者 边是什么label - 生成
vertex、edge、property的全局分布式唯一id - 自定义属性验证是否满足唯一性约束
主要流程如下图(建议依照源码一块查看,上述github地址已给出):

serialize阶段
主要是对上述prepare阶段准备好的数据进行序列化为二进制数据,为存储二进制数据到backend storage做准备; 另外获取本地锁 + 分布式锁数据插入(此处只是将数据插入到Hbase,插入成功并不代表获取成功)
过程中包含以下几种作用:
- 序列化所有
relation数据并存储,包含属性、label edge、normal edge - 获取属性对应
index需要更新的数据,并序列化存储; 包含组合索引和mixed index的处理 - 获取基于图实例的本地锁
- 获取了本地锁的前提前,获取
edge lock和index lock分布式锁(此处的获取锁只是将对应的KLV存储到Hbase中!存储成功并不代表获取锁成功,在commit阶段才会去检查是不是获取分布式锁成功!)
主要流程如下图:

commit阶段
主要是获取本地锁+分布式锁成功后,将对应序列化后的数据添加到对应的backend storage中;完成图数据插入过程! 在此阶段才会对图库中的真实数据开始影响,才会涉及到事务的回滚机制;
过程中包含以下几种作用:
- 判断分布式锁的状态,获取成功则进行数据持久化;不成功则失败
- 持久化
relation数据 - 持久化
index数据,包含组合索引存储到第三方存储;mixed index存储到第三方索引库中 - 删除对应的本地锁 和 分布式锁的占用
主要流程如下图:

二:edge数据写流程
针对于edge的写数据流程,整体的流程和vertex节点的数据写入相同,有几点不同,下面一一列出:
1、生成分布式唯一id的过程
导入Edge数据在生成edge的唯一id时,partition id的获取不再是随机获取,而是尝试获取边对应的out vertex的partition id; id的组成部分也不同,没有idPadding部分;
具体解释请看:《JanusGraph-分布式id生成策略》文章
2、在edge的导入中,没有同vertex数据导入,添加默认的节点是否存在属性和节点和节点对应label的边
3、获取edge对应的属性的index update时不同
在导入vertex数据时,将节点对应的属性作为relation存放在addRelation中,然后收集所有的属性relation循环获取index uodate;如下伪代码:
for (InternalRelation add : Iterables.filter(addedRelations,filter)) {
if (add.isProperty()) mutatedProperties.put(vertex,add); // 此处只操作属性类型的
mutations.put(vertex.longId(), add);
}
// 此处,收集节点对应属性对应的索引需要更新的数据、增加或删除节点时才有作用; 针对于插入edge的操作,不涉及此处
for (InternalVertex v : mutatedProperties.keySet()) {
indexUpdates.addAll(indexSerializer.getIndexUpdates(v,mutatedProperties.get(v)));
}
而在edge数据导入中,只将edge这条边作为relation插入到addRelation中,所以无法获取属性relation,转而通过收集过程中,对每个edge对应的所有属性进行分别获取;如下伪代码:
for (InternalRelation add : Iterables.filter(addedRelations,filter)) {
if (add.isProperty()) mutatedProperties.put(vertex,add); // 此处只操作属性类型的
mutations.put(vertex.longId(), add);
// 获取边包含的属性;在节点插入时没有作用,插入边数据时,获取边上的属性对应的索引; 只有edge操作中包含边属性,并且包含索引!
indexUpdates.addAll(indexSerializer.getIndexUpdates(add));
}
4、edge对应的relation数据,也就是当前插入的这个边,需要被序列化两次
一次是源节点+边关系,一次是目标节点+边关系(因为jansugraph是通过edge cut方式存储图数据的)
5、edge的数据插入过程中,edge的序列化组成部分不同于vertex的序列化组成部分;
不同点请看《Janusgraph-存储结构》文章
6、edge的数据插入中,edge的property和vertex的property组成不同!
edge中针对于sort key和signature key配置的属性,只将property value存储在对应位置。其他未被配置的属性值包含proeprty key label id + property value;
不同于vertex数据中的属性组成包含:proeprty key label id + property 唯一id +property value
三:源码分析
源码分析已经push到github:https://github.com/YYDreamer/janusgraph
数据写入的流程源码过多,就不在文章中给出分析了,具体请看github中源码分析注释吧
四:应用
基于数据序列化导入的源码博主将图数据的序列化逻辑抽取出来,生成一个工具包;
主要用于图数据的迁移和图数据库的初始化,适用于大数据量的导入,主要流程如下:
- 生成schema到图中
- 获取schema信息,缓存到内存中
- 调用api占用对应的id blocker,用于离线数据的分布式唯一id生成
- 调用抽取的序列化逻辑序列化节点和边数据
- 生成Hfile
- 将hfile导入到Hbase中
上述流程已经经过严格的验证并在生产环境中使用,具体之后会再出一篇文章介绍一下详细的设计与流程
五:总结
对于JanusGraph图数据的写入,主要分为3部分:
- schema的创建
- vertex节点数据的导入
- edge边数据的导入
上述主要分析了vertex和edge的数据导入,大致流程相似;也分析了两部分导入数据的差异;
其中涉及的分布式唯一id的生成逻辑 和 锁机制获取的逻辑,请看《图解Janusgraph系列-Lock锁机制(本地锁+分布式锁)分析》和《图解Janusgraph系列-分布式id生成策略分析》两篇文章!
针对于第三方索引的序列化存储逻辑,逻辑相对简单,此处没有给出,具体读者可以自主分析一下源码
码字不易,求个赞和star~
图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)的更多相关文章
- Eureka 系列(04)客户端源码分析
Eureka 系列(04)客户端源码分析 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 在上一篇 Eureka 系列(01)最简使用姿态 中对 Eureka 的简单用法做 ...
- Golang package轻量级KV数据缓存——go-cache源码分析
作者:Moon-Light-Dream 出处:https://www.cnblogs.com/Moon-Light-Dream/ 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须在文章中给出原文 ...
- Spring系列28:@Transactional事务源码分析
本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...
- Django(44)drf序列化源码分析(1)
序列化与反序列化 一般后端数据返回给前端的数据格式都是json格式,简单易懂,但是我们使用的语言本身并不是json格式,像我们使用的Python如果直接返回给前端,前端用的javascript语言 ...
- 大数据之Oozie——源码分析(一)程序入口
工作中发现在oozie中使用sqoop与在shell中直接调度sqoop性能上有很大的差异.为了更深入的探索其中的缘由,开始了oozie的源码分析之路.今天第一天阅读源码,由于没有编译成功,不能运行测 ...
- Java 集合系列(四)—— ListIterator 源码分析
以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比 Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素. Iterator 包含四个方法 ...
- Redis学习之底层链表源码分析
Redis底层链表的源码分析: 一.链表结点的结构(单个结点): // listNode 双端链表节点 typedef struct listNode { // 前置节点 struct listNod ...
- vue系列---snabbdom.js使用及源码分析(九)
一:什么是snabbdom? 在学习Vue或React中,我们了解最多的就是虚拟DOM,虚拟DOM可以看作是一颗模拟了DOM的Javascript树,主要是通过vnode实现一个无状态的组件,当组件状 ...
- Spring源码系列(二)--bean组件的源码分析
简介 spring-bean 组件是 Spring IoC 的核心,我们可以使用它的 beanFactory 来获取所需的对象,对象的实例化.属性装配和初始化等都可以交给 spring 来管理. 本文 ...
随机推荐
- 面试官:小伙子,给我说一下mysql 乐观锁和悲观锁吧
悲观锁介绍 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实现,往往依靠数据库 ...
- Camtasia中对给录制的视频添加视觉效果
视频创作和后期剪辑对很多人来说是一件很头痛的事,对着屏幕一段一段.一帧一帧的进行调整会让人十分的心烦,有时花费了大量时间剪出来的视频质量却不高,让人有一种想砸键盘的冲动. 这种问题,除非是原视频素材质 ...
- 能否安装 CrossOver 上没有的软件
系统兼容软件CrossOver可以像虚拟机一下帮助我们在Mac或者Linux上运行Windows应用程序,快速实现跨平台文件互通,所以我们也称它为类虚拟机. 不需要安装Windows操作系统的Cros ...
- Elasticsearch 理解mapping中的store属性
默认情况下,对字段值进行索引以使其可搜索,但不存储它们 (store). 这意味着可以查询该字段,但是无法检索原始字段值.在这里我们必须理解的一点是: 如果一个字段的mapping中含有store属性 ...
- Docker安装基本命令操作,带你了解镜像和容器的概念!
上一章节我们了解了Docker的基本概念,以及相关原理.这一章节进行实操. <Docker这么火爆.章节一:带你详尽了解Docker容器的介绍及使用> 一.Docker安装 声明:Dock ...
- Hibernate的配置跟简单创建一个表并插入一条数据
首先官网下载一个hibernate的架包,由于时间关系,博主已经分享到了百度网盘:https://pan.baidu.com/s/1Mw0Og3EKnouf84Njz9UicQ,提取码lens Hib ...
- 使用wapiti进网站进行安全性测试
1.安装wapiti --在命令终端输入 pip install wapiti3 (因为这个结合python使用,所以安装的版本要跟python兼容,因为我的python是3.6版本,所以安装的是wa ...
- SpringCloud 源码系列(1)—— 注册中心 Eureka(上)
Eureka 是 Netflix 公司开源的一个服务注册与发现的组件,和其他 Netflix 公司的服务组件(例如负载均衡.熔断器.网关等)一起,被 Spring Cloud 整合为 Spring C ...
- Generalizing from a Few Examples: A Survey on Few-Shot Learning 小样本学习最新综述 | 三大数据增强方法
目录 原文链接:小样本学习与智能前沿 01 Transforming Samples from Dtrain 02 Transforming Samples from a Weakly Labeled ...
- MySQL重做日志(redo log)
前面介绍了三种日志:error log.slow log.binlog,这三种都是 Server 层的.今天的 redo log 是 InnoDB引擎专有的日志文件. 为什么要有 redo log 用 ...