隨着 2.0 各版本的陸續發佈,Nebula Graph 迎來了一系列的改動,在存儲方面,影響最大的改動就是底層編碼格式進行了修改。Nebula Graph 的底層存儲是基於 KV 保存在 RocksDB 中,本文將介紹新老編碼格式的差別,以及爲何要修改存儲格式等一系列問題。git
咱們先簡單回顧下 1.0 版本的編碼格式,不熟悉的能夠參考這篇博客《Nebula 架構剖析系列(一)圖數據庫的存儲設計》。因爲在 1.0 版本中,點的 ID 只可以用整型來表示,因此底層全部 VertexID 都是以 int64 來保存的。github
給定任何一個 VertexID,通過 hash,能夠獲得對應的 PartID,所以對於一個點和這個點的全部邊(邊用起點計算 hash),都會映射到同一個分片中。須要指出的是,在 1.0 版本中,點和邊的第一個字節的 Type 是相同的。也就是說,對於一個點而言,它的全部 tag 並無在物理上連續保存,好比多是以下保存的。對於這個 src 這個點的三個 tag(tag1 tag2 tag3),實際上可能會被其餘邊隔開。數據庫
這個格式可以知足 1.0 絕大多數接口的須要,好比 fetch
和 go
都只須要指定對應前綴,就能獲取對應數據。微信
在 GA 以前發佈的版本,底層存儲格式其實和 1.0 是基本相同的。若是 VertexID 是整型,和 1.0 格式徹底一致。而若是 VertexID 類型支持 string,則從佔用 8 個字節的 int64 改爲了固定長度的 FIXED_STRING
,長度須要用戶在 create space
時候指定長度。對於不足的長度系統自動使用 \0
補齊,而超過指定長度的 VertexID 會直接報錯。markdown
在 GA 版本中,咱們對底層存儲格式進行了若干改動,所以此次版本升級時須要經過升級工具,將原有格式的數據轉換爲新格式的數據。以下是在 2.0 GA 版本中採用的存儲格式。架構
其中有幾個比較大的改動:ide
這些改動主要是基於如下幾點進行考慮的:工具
爲何 string ID 要使用 FIXED_STRING ? 若是不使用固定長度,則沒法使用前綴進行掃描。經過長度不足補齊,使得全部點之間和邊之間的各個前綴長度相同,從而進行相應的前綴查詢。oop
在邊裏面還保留一個字節的佔位符,主要是留給 TOSS(transaction on storage side)使用。主要用於標識一條邊的出邊和入邊是否完整插入了,這裏不詳細介紹,後續會有其餘文章進行詳盡的分析。post
MATCH
語句中大量使用)。若是按原先同一 Type + VertexID
前綴掃描,因爲點邊可能摻雜在一塊兒,會極大影響性能。而 Type 分離以後,按 VertexType + VertexID
前綴掃描,能夠快速獲取全部 tag。
在 1.0 版本中,因爲沒有取某個點的全部 tag 的需求,所以點和邊能夠按同一個前綴保存。不過在代碼層面,仍是有不小影響,例如 fetch 接口在 1.0 是按 VertexID 的前綴去掃描的,對於超級大點來講取 tag 性能比較差。另外若是使用 storage 提供的 scan 接口,想要獲取全圖的全部點,實際是掃描了整個 RocksDB。
除了點和邊的格式相關改動以外,索引的格式其實也有所改變。
一方面是 2.0 支持 NULL
後,索引也須要可以表示對應的語義。另外一方面是在 1.0 的版本中,對於索引中 string 的字段的處理,實際是按變長 string 處理。所以在 LOOKUP
語句中只要使用了帶 string 字段的索引,就只能使用等值查詢。而在 2.0 的版本中,索引的 string 字段和數據中的 VertexID 同樣,使用固定長度的 FIXED_STRING,LOOKUP
語句中帶 string 字段的索引可以使用範圍查詢,例如 LOOKUP ON index1 WHERE col > "aaa"
。有關索引部分的功能和修改,後續也會再有其餘文章介紹。
以上,爲本次 Nebula Storage 2.0 存儲格式講解。
喜歡這篇文章?來來來,給咱們的 GitHub 點個 star 表鼓勵啦~~ 🙇♂️🙇♀️ [手動跪謝]
交流圖數據庫技術?交個朋友,Nebula Graph 官方小助手微信:NebulaGraphbot 拉你進交流羣~~