近期工作中要做一些圖譜的應用,於是這幾天就調研了下圖資料庫,最後就有了本文。ps:本人第一次做圖譜相關的應用,具體怎麼構建也還不清楚,大家有什麼資料、建議歡迎私信、留言的。
圖領域的問題
整個圖領域,所有要解決問題都能分為兩大類:
- Technologies used primarily for transactional online graph persistence, typically accessed directly in real time from an application(線上處理)
- Technologies used primarily for offline graph analytics, typically performed as a series of batch steps(離線分析)
另一種分類是從採用的技術上,3 種主要的圖資料模型:
- property graph
- Resource Description Framework (RDF) triples
- hypergraphs
市面上大多數圖資料庫都是基於 property graph 來做的。
圖資料庫
看圖資料庫的時候,我們從兩個技術點切入:
- The underlying storage
- The processing engine
像 Titan 使用的不是 native 儲存,後端可以使用
- Apache Cassandra
- Apache HBase
- Oracle BerkeleyDB
而 neo4j 用的就都是 native graph storage and native graph processing
此處解釋下什麼叫 native graph storage 和 native graph processing
native graph processing
如果儲存具有 index-free adjacency 屬性,則稱為具有 native processing 屬性。
那什麼叫 index-free adjacency?
如果每個節點直接指向關聯的節點,相當於每個節點都有一個自己的區域性索引,比起全域性索引來說,成本更低,因此速度也更快
native graph storage
index-free adjacency 是圖資料庫相比於傳統的 mysql 的優勢的核心 key,那麼圖資料庫用什麼結構去儲存 index-free adjacency 是關鍵設計點。
架構上生層是對外訪問的 api,右邊是事務管理,左邊有 cache 等,下面我們看下 disk 上儲存的結構:
neo4j 在磁碟上會分不同的 store file 儲存
- neostore.nodestore.db:儲存 node
- neostore.propertystore.db:儲存屬性
- neostore.relationshipstore.db:儲存關係
一個重要的設計點是 store 中儲存的 record 都是固定大小的,固定大小帶來的好處是:因為每個 record 的大小固定,因此給定 id
就能快速進行定位。
具體結構是:
上圖第一個是 node record 的結構:
- 1byte:in-use flag,表明該 node 是否在使用
- 4byte:第一個 relation id
- 4byte:第一個 property id
- 5byte:label 資訊(可能直接 inline 儲存)
- 1byte:reversed
下面是 relation record 的結構:
剛開始是開始和結束節點的 node id,接著是 relation type pointer,然後開始和結束節點的前驅和後繼 relation id
更形象一點的圖
一個可能的搜尋過程是:對於給定的一個 node record,可以通過 id 進行簡單的偏移計算得到 node,然後通過 relation_id 定位到 relation record,然後得到 end node id,通過偏移計算得到 node
雙向儲存
還有一個問題:圖中節點的關係是有方向的,怎麼記錄這種方向呢?如果方向是雙向的,我們難道要儲存兩個 relation 嗎?
看例子:
這種 partner 的關係天然就是雙向的,但是我們儲存的時候,難道要儲存兩個關係嗎,如下圖:
那肯定是不需要的,這種儲存就是一種浪費,那到底 neo4j 中是怎麼儲存 partner 這種雙向關係的呢?
答案是:以任意一個節點為開端,另一個為尾端,即儲存成為單向的關係
在 neo4j 中任意的關係都有一個 start node 和一個 end node,而且 start node 和 end node 都會有個關聯的雙向連結串列,這個雙向連結串列中就記錄了從該節點出去和進入的所有關係,一個例項是:
圖片來自:neo4j 底層儲存結構分析 (1)
上圖中 B 節點的 prev 和 next 我們就能看到在這個連結串列中,B 有時候是 start node 有時候是 end node。
至此我們就對圖資料庫有了個大概的瞭解了,後續的分析會隨著專案的推進持續輸出。
待完成
下面是今後需要跟進的一些工作
- 效能測試
- 分散式方案
- Titan 調研
- ....
參考
neo4j 底層儲存結構分析 (1)
Modelling Data in Neo4j: Bidirectional Relationships
graph database