圖資料庫奧祕初探

顓頊發表於2017-03-30

近期工作中要做一些圖譜的應用,於是這幾天就調研了下圖資料庫,最後就有了本文。ps:本人第一次做圖譜相關的應用,具體怎麼構建也還不清楚,大家有什麼資料、建議歡迎私信、留言的。

圖領域的問題

整個圖領域,所有要解決問題都能分為兩大類:

  1. Technologies used primarily for transactional online graph persistence, typically accessed directly in real time from an application(線上處理)
  2. Technologies used primarily for offline graph analytics, typically performed as a series of batch steps(離線分析)

另一種分類是從採用的技術上,3 種主要的圖資料模型:

  1. property graph
  2. Resource Description Framework (RDF) triples
  3. hypergraphs

市面上大多數圖資料庫都是基於 property graph 來做的。

圖資料庫

看圖資料庫的時候,我們從兩個技術點切入:

  1. The underlying storage
  2. 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

相關文章