你们好,我是洋仔
,JanusGraph图解系列文章,实时更新
~java
源码分析相关可查看github(码文不易,求个star~)
: https://github.com/YYDreamer/janusgraphgit
下述流程高清大图地址:https://www.processon.com/view/link/5f471b2e7d9c086b9903b629github
版本:JanusGraph-0.5.2数据库
转载文章请保留如下声明:编程
做者:洋仔聊编程
微信公众号:匠心Java
原文地址:https://liyangyang.blog.csdn.net/api
JanusGraph的数据导入过程主要分为三阶段:prepare(准备)、serialize(序列化)、commit(提交);不一样阶段有不一样的做用,以下:缓存
下面咱们分别从导入vertex
节点和edge
边两部分来分析写流程微信
建议依据源码同步看本文章,便于理解!分布式
下面vertex
节点数据的导入,工具
主要是依据当前给定的参数,组装出对应的vertex 或者 edge 对象;对象中包含对应的id、索引信息、属性信息和锁信息等;
过程当中包含如下几种做用:
vertex exist
属性,值为true,标识当前节点是否存在label edge
边,标识当前的节点 或者 边是什么labelvertex
、edge
、property
的全局分布式惟一id主要流程以下图(建议依照源码一块查看,上述github地址已给出):
主要是对上述prepare
阶段准备好的数据进行序列化为二进制数据,为存储二进制数据到backend storage
作准备; 另外获取本地锁 + 分布式锁数据插入(此处只是将数据插入到Hbase,插入成功并不表明获取成功)
过程当中包含如下几种做用:
relation
数据并存储,包含属性、label edge、normal edgeindex
须要更新的数据,并序列化存储; 包含组合索引和mixed index
的处理edge lock
和 index lock
分布式锁(此处的获取锁只是将对应的KLV存储到Hbase中!存储成功并不表明获取锁成功,在commit阶段才会去检查是否是获取分布式锁成功!)主要流程以下图:
主要是获取本地锁
+分布式锁
成功后,将对应序列化
后的数据添加到对应的backend storage
中;完成图数据插入过程! 在此阶段才会对图库中的真实数据开始影响,才会涉及到事务的回滚机制;
过程当中包含如下几种做用:
relation
数据index
数据,包含组合索引存储到第三方存储;mixed index
存储到第三方索引库中主要流程以下图:
针对于edge
的写数据流程,总体的流程和vertex
节点的数据写入相同,有几点不一样,下面一一列出:
一、生成分布式惟一id的过程
导入Edge数据在生成edge的惟一id时,partition id
的获取再也不是随机获取
,而是尝试获取边对应的out vertex
的partition id
; id的组成部分也不一样,没有idPadding
部分;
具体解释请看:《JanusGraph-分布式id生成策略》文章
二、在edge
的导入中,没有同vertex
数据导入,添加默认的节点是否存在属性
和节点和节点对应label的边
三、获取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)); }
四、edge
对应的relation数据,也就是当前插入的这个边,须要被序列化两次
一次是源节点+边关系,一次是目标节点+边关系(由于jansugraph是经过edge cut方式存储图数据的)
五、edge
的数据插入过程当中,edge的序列化组成部分不一样于vertex的序列化组成部分;
不一样点请看《Janusgraph-存储结构》文章
六、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中源码分析注释吧
基于数据序列化导入的源码博主将图数据的序列化逻辑抽取出来,生成一个工具包;
主要用于图数据的迁移和图数据库的初始化,适用于大数据量的导入,主要流程以下:
上述流程已经通过严格的验证并在生产环境中使用,具体以后会再出一篇文章介绍一下详细的设计与流程
对于JanusGraph图数据的写入,主要分为3部分:
上述主要分析了vertex
和edge
的数据导入,大体流程类似;也分析了两部分导入数据的差别;
其中涉及的分布式惟一id
的生成逻辑 和 锁机制获取
的逻辑,请看《图解Janusgraph系列-Lock锁机制(本地锁+分布式锁)分析》和《图解Janusgraph系列-分布式id生成策略分析》两篇文章!
针对于第三方索引的序列化存储逻辑,逻辑相对简单,此处没有给出,具体读者能够自主分析一下源码
码字不易,求个赞和star~