1. 程式人生 > 其它 >Nebula Graph 的 KV 儲存分離原理和效能測評

Nebula Graph 的 KV 儲存分離原理和效能測評

本文首發於 Nebula Graph Community 公眾號

1. 概述

過去十年,圖計算無論在學術界還是工業界熱度持續升高。相伴而來的是,全世界的資料正以幾何級數形式增長。在這種情況下,對於資料的儲存和查詢的要求越來越高。因此,圖資料庫也在這個背景下引起了足夠的重視。根據世界知名的資料庫排名網站 DB-Engines.com 的統計,圖資料庫至 2013 年以來,一直是“增速最快”的資料庫類別。雖然相比關係型資料庫,圖資料庫的佔比還是很小。但由於具有更加 graph native 的資料形式,以及針對性的關係查詢優化,圖資料庫已經成為了關係型資料庫無法替代的資料庫型別。此外,隨著資料量的持續爆炸性上漲,人們對於資料之間的關係也越來越重視。人們希望通過挖掘資料之間的關係,來獲取商業上的成功,以及獲得更多人類社會的知識。因此我們相信,天生為儲存資料關係和資料探勘而優化的圖資料庫會在資料庫中持續保持高速增長。

圖1: 關係型和圖資料庫在關係查詢的效能對比

圖1 顯示了查詢資料之間多跳關係(圖的深度優先或者廣度優先搜尋)的關係型資料庫和圖資料庫的效能差異。(這裡我們雖然以 Neo4j 為例,但 Nebula 無論在效能還是在可擴充套件性上都是優於 Neo4j 的)。
雖然關係查詢效能勝於關係型資料庫,當前主流的圖資料庫在多跳查詢(高深度圖遍歷)上的效能還是災難性的。尤其對於大資料量, 分散式系統來說更是如此。而儲存的效能又往往是資料庫效能的瓶頸。在我們的簡單測試(單機,1GB/s SSD, 73GB 資料)中,簡單的三跳查詢並返回屬性 P50 延遲可以達到 3.3s,P99 延遲可以達到 9.0s。而且隨著查詢語句的複雜度提升,系統很可能變得不可用。

目前,Nebula 使用 RocksDB 作為底層儲存引擎。我們知道圖資料庫的主要 workload 是對於關係的多層次遍歷,一次查詢往往需要多次對儲存引擎的讀取。因此對 RocksDB 一次讀取的效能劣勢在圖查詢中會被多次放大。這也是為什麼多跳圖查詢延遲巨大。反過來說,對於單次 RocksDB 查詢的效能提升也將在 Nebula 查詢中被多次放大。因此如何優化 RocksDB,使得 RocksDB 適配圖資料庫的 workload,成為優化儲存端效能的重中之重。

RocksDB 的核心資料結構是 LSM-Tree。所有 key 和 value 都存於 LSM-Tree 中。但這種設計有一個缺點:由於 value 往往比 key 大,LSM-Tree 中大部分的空間是用來存 value 的。一旦 value 特別大,那麼 LSM-Tree 會需要更深的 level 來儲存資料。而 LSM-Tree 的讀寫效能是直接跟層數負相關的。層數越深,可能帶來的讀寫放大就越多,效能也就越差。因此我們提出使用 KV 分離來儲存圖資料庫:將值較小的資料存在 LSM-Tree 中,而將值較大的資料存在 log 中。這樣操作,大 value 並不存在 LSM-Tree 中,LSM-Tree 的高度會降低。而 RocksDB 相鄰兩層的 size 是 10 倍關係,即便減少一層 LSM-Tree 高度,也能大大增加 Cache 的可能性,從而提高讀效能。此外,KV 分離帶來的讀寫放大的減少也能加快讀寫速度。

在我們的測試中,我們發現 KV 分離對於圖查詢的效能具有巨大提升。對於小 value 的查詢延遲降低可以高達 80.7%。而對於大 value 的查詢,延遲降低相對較少,但也可以達到 52.5%。考慮到大部分大 value 的資料是冷資料而且佔絕大多數的,因此總體效能的提升將更接近於對於小 value 的查詢。

值得注意的是,Nebula 從 3.0.0 版本開始已經提供了 KV 分離的功能。使用者可以通過 nebula-storaged 的配置檔案來配置 KV 分離的功能。

2. KV 分離技術

上文說到 LSM-Tree 存在比較嚴重的讀寫放大問題。這是因為每次 Compaction 都需要同時對 key 和 value 進行 Compaction,而且這個放大率會隨著資料庫的資料增加而增大(對於 100GB 資料,寫放大可以達到 300 多倍)。這對 LevelDB 來說也許不是那麼嚴重的問題。因為 LevelDB 是為 HDD 設計的。對 HDD 來說,隨機讀寫效能遠遠低於順序讀寫(1,000 倍差距)。只要讀寫放大比例小於 1,000 就是合算的。但對於 SSD 來說,隨機和順序讀寫效能差距沒那麼大,尤其對於 NVMe SSD(如下圖)。

圖2. NVMe SSD 效能

因此大量的讀寫放大會浪費頻寬。於是,Lu. etc 在 2016 年提出了 KV 分離的儲存結構: https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf。論文的核心思想是比較小的 key 存在 LSM-Tree 中,value 放在 log 中。這樣 LSM-Tree 每一層可以存更多的 KV,同樣的資料量,層級會比較低,這樣可以提高讀寫的效率。對於寫沒那麼多的 workload,Compaction 時省下來的寫頻寬可也可以降低讀的 P99 延遲。當然這個設計也有一定的問題。相比 SSTable 中的 KV 絕對有序而言,log 中的 value 只是相對有序(按照 key 排序)。因為每次插入資料都是 append 到 log 中,必須依賴後續的 Garbage Collection(下簡稱 GC)來使 log 中的資料也變得相對有序。因此對於大規模的範圍查詢 Range Query,並且是小 value(64B),效能可能會差。

目前 RocksDB 的最新版本已經支援了 KV 分離:http://rocksdb.org/blog/2021/05/26/integrated-Blob-db.html。它將分離後的 value 存到了多個 log 上(.blob file)。每一個 SST 對應多個 Blob。Blob 的 GC 是在 SST Compaction 的時候觸發。

3. Nebula KV 分離效能測試

在這裡,我們測試 Nebula 在不同的資料和查詢下的 KV 分離的效能,包括:

  1. 不查詢屬性的拓撲查詢
  2. 分別對小 value 和大 value 點的屬性查詢
  3. 對邊的屬性查詢
  4. 資料插入
  5. 沒有大 value 情況下 KV 分離的影響。

3.1 測試環境

本次測試主要使用了一臺物理機。Node A 具有 56 核 Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz,256GB 記憶體,圖資料儲存在 1.5 TB 的 NVMe SSD 上。

測試資料都是由 LDBC(https://github.com/ldbc)生成。為了測試 KV 分離效果,我們準備了兩類資料:一類全是小 value,另一類是大 value 和小 value 混合。對於前者,我們使用預設 LDBC 的設定,如圖 3。

圖3. LDBC 預設 Text 和 Comment value 設定

對於後者我們將 text、comment、large post 和 large comment 全部設定成 min size 4KB、max size 64KB。這是屬於大 value,由 REPLY_OF 邊連線。我們保留 Person 的預設設定,屬於小 value,由 KNOW 邊連線,其 value 的具體分佈參考表 1。

Bucket Percentage
0-32B 2.67%
32B-128B 0.04%
128B-160B 96.60%
160B-192B 0.69%

表1. Person value 大小分佈

據此我們準備了兩個資料,見表2。

資料集 value 大小 資料集大小 Comment
Data1 < 200B Person
Default for others 37GB scale * 30
Data2 <200B Person
Min 4K, Max 64K for others 73GB scale * 3

表2. 資料集詳情

這裡我們使用 nebula-bench 中不同的測試語句,包括 1 跳、2 跳、3 跳查詢和 FindShortestPath(測試中縮寫 FSP)、INSERT 語句。此外,我們還添加了 5 跳查詢來測試更極限的效能情況。同一測試重複執行 5 次,後文將使用 NoSep 和 Sep 分別指代未配置 KV 分離和配置了 KV 分離

3.2 KV 分離後 RocksDB 的內部結構

我們分別使用 KV 分離和不分離的方式匯入資料集 Data2。對於 KV 分離的設定,我們設定大於某個閾值的資料存在 Blob 中(分離),小於閾值的資料存在 SST 中(不分離)。這裡以 100B 閾值為例。
對於 NoSep,匯入資料後,一共有 13GB 資料,217 個 SST。對於 Sep,匯入資料後,一共有 16GB 資料,39 個 SST。圖 4. 和圖 5. 分別顯示 NoSep 和 Sep 的 LSM-Tree 內部情況。



圖 4. KV 不分離 RocksDB 有三層 LSM-Tree

圖 5. KV 分離後 RocksDB 有兩層 LSM-Tree

可以看到 NoSep 使用了 3 層 LSM-Tree,而 Sep 只有兩層。考慮到我們配置 RocksDB L1 為 256MB, L2 為 2.5GB,L3 為 25GB。單單層數從 3 層減少到 2 層可能就是能否將所有資料存入 Cache 的區別。

3.3 拓撲查詢的效能

對於圖的查詢既有屬性查詢也有拓撲查詢。首先,我們測試 KV 分離對於非值(拓撲)查詢的影響。拓撲查詢對 RocksDB 不會呼叫 GET 操作,而只有 SEEK 和 NEXT 操作。而對於拓撲查詢,又分為對於 KNOW 關係和 REPLY_OF 關係進行 walk。值得注意的是,雖然這兩種關係(邊)所連線的點的屬性大小存在很大差別,但拓撲查詢只涉及邊。我們將同一份 Data2 資料集分別匯入到 KV 分離和不分離的 Nebula 中,並且從同一個原始資料中獲取查詢語句進行查詢。

查詢效能跟 Cache 機制有關。RocksDB 主要使用了自身的 LRU Cache,也叫 Block Cache,和 OS 的 Page Cache。其中 Block Cache 儲存的是解壓縮後的 Block,而 Page Cache 儲存的是壓縮後的 Block。Block Cache 雖然效率更高,但是空間使用率低。在生產環境中,我們推薦將 Block Cache 大小設定為 1/3 記憶體。本次測試將分別比較不使用 Block Cache(只有 OS Page Cache),1/3記憶體(80GB)大小的 Block Cache + OS Page Cache,和 direct I/O (既沒有 Block Cache,也沒有 OS Page Cache)各自的效能。















圖 6. KV 分離對於 KNOW 關係拓撲查詢的效能影響

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.9% 1.0% 0.7%
Go 2 Step 4.7% 5.3% 5.1%
Go 3 Step 15.9% 21.4% 9.4%
Go 5 Step 11.2% 12.2% 7.9%
FSP 6.8% 10.1% 2.7%

表 3a. KV 分離對於 KNOW 關係拓撲查詢的延遲減少(Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 1.2% 1.1% 1.5%
Go 2 Step 8.3% 10.0% 7.1%
Go 3 Step 26.8% 43.2% 29.6%
Go 5 Step 31.7% 38.3% 21.6%
FSP 8.6% 12.4% 3.9%

表 3b. KV 分離對於 KNOW 關係拓撲查詢的延遲減少(Block Cache + Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 1.1% 1.0% 1.8%
Go 2 Step 14.3% 15.0% 12.4%
Go 3 Step 17.4% 17.8% 16.0%
Go 5 Step 10.5% 3.0% 17.2%
FSP 15.8% 21.7% -3.6%

表 3c. KV 分離對於 KNOW 關係拓撲查詢的延遲減少(direct I/O)

圖6 和表 3顯示了 Nebula 對於 KNOW 關係查詢的測試結果。針對資料集 Data2 的資料分佈特性,我們測試了分別以 100B 和 4KB 作為 KV 分離的閾值。可以很明顯地看到 KV 分離極大地提升了 Data2 的查詢效能。對於圖遍歷深度較淺的查詢( Go 1 Step),KV 分離的延遲降低比較少,在 100B 閾值下的 P50 延遲降低大約在 1%。但對於更深的查詢,其提升就非常明顯了,比如:對於 Go 3 Step,在使用大 Block Cache 下(表 3.b),在 100B 閾值下 P50 延遲降低可以達到 43.2%。而尋找最短路徑對於圖的遍歷的深度往往在 1 跳和多跳查詢之間,因此其效能提升是多跳查詢的平均。

注意這裡 KV 分離在 Go 5 Step 並沒有進一步的效能提升,可能因為對於更深的遍歷,其主要瓶頸不在儲存。相比於 KV 分離之於不分離的效能提升,100B 和 4KB 的閾值區別並不大。因此在表 3 中,我們以 100B 閾值為例展示了具體的延遲減少百分比。

另外,對於有 Cache 的情況下(Block 或 Page Cache),所有資料都可以快取,此時 KV 分離效能比不分離效能更好,也說明 KV 分離後記憶體中的資料訪問效率更高。具體的原因可能是 SST 本來就不是記憶體訪問的最佳資料結構。因此小 LSM-Tree 相比大 LSM-Tree 帶來的效能提升會比較明顯。















圖 7. KV 分離對於 REPLY_OF 拓撲查詢的效能 (注意這裡 Go 3 Step 和 Go 5 Step 之間效能並沒有多大差別。這是因為 Go 5 step 只有 0.6% 的查詢返回了非 0 結果。因此 Go 5 Step 本質上不會比 Go 3 Step 多 walk 多少邊。)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 1.1% 1.8% 0.1%
Go 2 Step 1.2% 1.3% 1.1%
Go 3 Step 1.2% 1.4% 0.8%
Go 5 Step 1.1% 1.2% 1.0%
FSP 6.4% 9.1% 3.3%

表 4a. KV 分離對於 REPLY_OF 關係拓撲查詢的延遲減少(Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.8% 0.9% 0.2%
Go 2 Step 1.2% 1.4% 0.2%
Go 3 Step 1.3% 1.6% 0.4%
Go 5 Step 1.3% 1.6% 0.7%
FSP 5.4% 8.0% 2.4%

表 4b. KV 分離對於 REPLY_OF 關係拓撲查詢的延遲減少(Block Cache + Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 1.2% 1.4% 0.2%
Go 2 Step 1.3% 1.7% 0.0%
Go 3 Step 1.3% 1.5% 0.6%
Go 5 Step 1.8% 2.0% 0.7%
FSP 9.1% 13.3% -4.3%

表 4c. KV 分離對於 REPLY_OF 關係拓撲查詢的延遲減少(direct I/O)

圖 7. 和表 4. 展示了對於 REPLY_OF 關係的查詢結果。此時,可以看到 KV 分離雖然效能提升效果不明顯,但也是有確定的提升的。注意這裡 Go 3 Step 和 Go 5 Step 之間效能並沒有多大差別。這是因為 Go 5 Step 只有 0.6% 的查詢返回了非 0 結果。因此 Go 5 Step 本質上不會比 Go 3 Step 多 walk 多少邊。注意這裡由於效能差別不大,我們只展示了 4K 閾值下 KV 分離和不分離的對比情況。

3.4 點的屬性查詢效能

在這部分,我們來測試 KV 分離對於屬性(值)查詢的效能影響。按照 KV 分離的理論,傳統的 LSM-Tree 對於讀效能的影響主要來源於讀放大。而讀放大要通過 GET 操作才能體現得明顯。而屬性查詢恰好能體現讀放大的影響。
首先,我們測試對於點的屬性查詢。同上,測試分為對於小 value 和大 value 進行 walk。












圖 8. KV 分離對於小 value 屬性查詢的效能

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 36.2% 37.6% 32.4%
Go 2 Step 34.0% 35.5% 28.6%
Go 3 Step 37.4% 40.3% 29.3%
Go 5 Step 16.3% 19.0% 14.3%

表 5a. KV 分離對於小 value 屬性查詢的延遲減少(Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 35.6% 37.8% 31.6%
Go 2 Step 29.6% 31.1% 23.4%
Go 3 Step 33.8% 36.0% 25.4%
Go 5 Step 19.1% 33.5% 9.9%

表 5b. KV 分離對於小 value 屬性查詢的延遲減少(Block Cache + Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 78.6% 78.9% 77.9%
Go 2 Step 80.8% 81.3% 78.7%
Go 3 Step 75.8% 77.3% 72.1%
Go 5 Step 53.2% 46.3% 37.5%

表 5c. KV 分離對於小 value 屬性查詢的延遲減少(direct I/O)

圖 8 和表 5 顯示了 KV 分離對於小 value 進行 walk 並返回值(屬性)查詢的效能影響。這是通過對 KNOW 關係進行查詢並返回節點屬性實現的。我們可以看到以 4K 為閾值情況下,KV 分離 P50 延遲降低可以達到 81.3%,而 P99 延遲降低可以達到 78.7%。這主要得益於對於 KV 分離對於點查詢的效能提升巨大,這也和 RocksDB 對於 KV 分離的測試結果一致。另外,可以看到 KV 分離對於 direct I/O 的效能提升最大。這是因為 KV 分離對讀效能的提升主要來源於讀放大的減少和 Cache 命中率的提升。但由於磁碟 I/O 效能遠小於記憶體訪問,所以讀放大的減小對於效能提升更加明顯。而讀放大隻在產生 I/O 的情況下才會產生。所以這裡 direct I/O 主要是體現讀放大的減小對於效能的提升。












圖 9. KV 分離對於大 value 屬性查詢的效能

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 7.1% 6.7% 8.8%
Go 2 Step 3.8% 4.2% 3.8%
Go 3 Step 1.9% 1.8% 1.6%
Go 5 Step 0.5% 1.0% -0.6%

表 6a. KV 分離對於大 value 屬性查詢的延遲減少(Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.7% 0.5% 1.3%
Go 2 Step 0.9% 0.9% 1.0%
Go 3 Step 1.5% 1.6% 1.6%
Go 5 Step 1.4% 1.7% 1.0%

表 6b. KV 分離對於大 value 屬性查詢的延遲減少(Block Cache + Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 52.3% 52.5% 51.1%
Go 2 Step 26.4% 22.9% 24.3%
Go 3 Step 7.6% 1.0% 16.8%
Go 5 Step 2.4% 2.4% 3.8%

表 6c. KV 分離對於大 value 屬性查詢的延遲減少(direct I/O)

圖 9 和表 6 通過對 REPLY_OF 關係進行 walk 並返回終點 value,體現了 KV 分離對於讀取大 value 效能的影響此時 KV 分離在比較淺的遍歷的時候,效能提高反而較大,而對於較深的遍歷沒有太多影響。這主要是因為對於 REPLY_OF 關係,99.99% 的查詢存在 1 跳及以上關係、只有 50.7 %的資料之間存在 2 跳及以上關係、只有 16.8% 的資料之間存在 3 跳及以上關係。因此隨著查詢跳數上升,需要實際去 GET 屬性的查詢比例反而減少。因此對於實際 GET property 比例最高的查詢 Go 1 Step,KV 分離對於其效能提升反而最多。而對於其他查詢,KV 分離對於效能的影響會更接近於 3.3 節中對於 REPLY_OF 關係的拓撲查詢。

3.5 邊的屬性查詢效能

再來測試對於邊屬性的查詢效能。根據之前的測試結果,我們知道 REPLY_OF 邊連線的深度比較淺,較深的查詢也會退化成淺查詢。因此,這裡我們僅關注對於 KNOW 關係的邊屬性查詢。












圖 10. KV 分離對於邊屬性查詢的效能影響

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.5% 0.6% -0.5%
Go 2 Step 3.3% 4.2% 2.8%
Go 3 Step 11.4% 25.8% 1.2%
Go 5 Step 15.0% 24.3% 6.6%

表 7a. KV 分離對於邊屬性查詢的延遲減少(Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.0% 0.2% 0.1%
Go 2 Step -0.3% -0.1% -0.6%
Go 3 Step 4.2% 13.0% -1.7%
Go 5 Step 0.7% 4.7% -0.1%

表 7b. KV 分離對於邊屬性查詢的延遲減少(Block Cache + Page Cache)

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.5% 0.2% 1.4%
Go 2 Step 4.0% 4.9% 2.1%
Go 3 Step 12.5% 12.9% 10.2%
Go 5 Step 6.9% 1.2% 13.4%

表 7c. KV 分離對於邊屬性查詢的延遲減少(direct I/O)

圖 10 和表 7 顯示了測試結果。可以看出此種情況下 KV 分離的效能提升大大降低。因為在 LDBC 資料集中,邊上的屬性只有 creationDate,小於測試中 KV 分離的閾值 100B。因此無論是否使用 KV 分離,邊上的屬性都儲存在 LSM-Tree 上。只是 KV 分離後,LSM-Tree 的大小變小,Cache 效率更高。因此,KV 分離對於 LDBC 資料集中的邊上屬性查詢效能提升較小

3.6 資料插入的效能

這裡,我們也測試下 KV 分離對於資料插入的效能影響。由於 Cache 對於 RocksDB 的 PUT 的效能影響不大,這裡只測試了只有 OS Page Cache 的場景。我們繼續使用資料集 Data2,並且每次插入查詢都執行 10 分鐘,以確保 Compaction 會被觸發。


圖 11. KV 分離對資料插入的效能影響

圖 11 顯示了資料插入效能。一個是插入 Person 資料,屬於小 value。另一個是插入 Comment 資料 (至少4KB),屬於大 value。我們可以看到 KV 分離對於插入大 value 具有比較明顯的效能提升。其收益主要來自於更少的 Compaction。而對於小 value 的插入,由 PUT 導致的寫放大在 RocksDB 中並不明顯。但另一方面,在每一個 KV Flush 到 L0 的時候,KV 分離帶來的額外一次寫的開銷(需要同時寫 SST 和 Blob)卻比較明顯。因此,在 value 比較小的時候,KV 分離的寫效能會受影響

3.7 如果我的資料集全是小 Value?

我們已經知道如果資料集中有大 value,那麼無論是拓撲查詢還是值查詢,KV 分離都能帶來巨大的效能提升。那如果沒有大 value 呢?是否存在副作用?

這一節我們測試了 KV 分離對於沒有大 value 情況的效能影響。

首先需要注意的是,KV 分離並不是在任何時候都能對 RocksDB 帶來效能提升。尤其在小 value 情況下, Range Query 效能是會變差的。我們這裡測試也不會覆蓋所有小 value 的情況。我們選擇使用資料集 Data1,針對預設的 LDBC 資料進行測試。












圖 12. KV 分離對小 value 拓撲結構和屬性查詢的效能影響

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 3.2% 3.5% 2.5%
Go 2 Step 5.1% 7.0% -1.4%
Go 3 Step 2.1% 3.5% 0.4%
FSP 2.6% 3.7% 1.1%

表 9a. 所有小 value 查詢的延遲降低

Test Avg reduction P50 reduction P99 reduction
Test Avg reduction P50 reduction P99 reduction
Go 1 Step 0.2% -1.5% 7.7%
Go 2 Step 11.2% 9.3% 19.2%
Go 3 Step 3.4% 1.6% 8.2%
FSP 5.9% 8.3% 1.9%

表 9b. 所有小 value 查詢的延遲降低

Test Avg reduction P50 reduction P99 reduction
Go 1 Step 17.8% 19.1% 15.1%
Go 2 Step 22.2% 24.9% 19.1%
Go 3 Step 58.1% 68.1% 28.1%
FSP 26.2% 35.6% 3.2%

表 9c. 所有小 value 查詢的延遲降低

圖 12 展示了在全是小 value 情況下,將 KV 分離的閾值置成 100B 的效能。其中,在 Go 1 Step、Go 2 Step、Go 3 Step 中,我們提取了目標節點的屬性,是屬性查詢,FindShortestPath 是不返回值的拓撲查詢。可以看到,雖然效能提升不如資料集 Data2,但是延遲也是有降低的,在 direct I/O 情況下尤為明顯。注意,我們這裡沒有展示 Go 5 Step,因為 Go 5 Step 的壓力測試中出現了超時情況,因此測試結果不準確。

總之,我們證明了無論是大 value 還是小 value,拓撲查詢還是值查詢,KV 分離都是能帶來效能提升的。

4. 結論

我們提出使用 KV 分離來儲存圖資料庫:將值較小的資料存在 LSM-Tree 中,而將值較大的資料存在 log 中。這樣由於大 value 並不存在 LSM-Tree中,LSM-Tree 的高度可能因此降低,增加 Cache 的可能性,從而提高讀效能。哪怕不考慮 Cache,KV 分離帶來的讀寫放大的減少也能加快讀寫速度。在我們的測試實驗中,我們發現 KV 分離對於圖查詢的效能具有巨大提升。對於小 value 的查詢延遲降低可以高達 80.7%。而對於大 value 的查詢,延遲降低相對較少,但也可以達到 52.5%。考慮到大部分大 value 的資料是冷而且佔絕大多數的,因此總體效能的提升將更接近於對於小 value 的查詢。從 Nebula Graph 3.0.0版本開始,可以通過 nebula-storaged 的配置檔案來配置 KV 分離的功能。


交流圖資料庫技術?加入 Nebula 交流群請先填寫下你的 Nebula 名片,Nebula 小助手會拉你進群~~

關注公眾號

Nebula Graph:一個開源的分散式圖資料庫