你們好,我是洋仔
,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~