中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 數據庫 > 
  • Jepsen 測試框架在圖數據庫 Nebula Graph中的實踐分析

Jepsen 測試框架在圖數據庫 Nebula Graph中的實踐分析

發布時間:2021-11-30 17:00:54 來源:億速云 閱讀:147 作者:柒染 欄目:數據庫

Jepsen 測試框架在圖數據庫 Nebula Graph中的實踐分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Jepsen 簡介

Jepsen 是一款用于系統測試的開源軟件庫,致力于提高分布式數據庫、隊列、共識系統等的安全性。作者 Kyle Kingsbury 使用函數式編程語言 Clojure 編寫了這款測試框架,并對多個著名的分布式系統和數據庫進行了一致性測試。目前 Jepsen 仍在 GitHub 保持活躍,能否通過 Jepsen 的測試已經成為各個分布式數據庫對自身檢驗的一個標桿。

Jepsen 的測試流程

Jepsen 測試推薦使用 Docker 搭建集群。默認情況下由 6 個 container 組成,其中一個是控制節點(control node),另外 5 個是數據庫的節點(默認為 n1-n5)。控制節點在測試程序開始后會啟用多個 worker 進程,并發地通過 SSH 登入數據庫節點進行讀寫操作。

測試開始后,控制節點會創建一組進程,進程包含了待測試分布式系統的客戶端。另一個 Generator 進程產生每個客戶端執行的操作,并將操作應用于待測試的分布式系統。每個操作的開始和結束以及操作結果記錄在歷史記錄中。同時,一個特殊進程 Nemesis 將故障引入系統。

測試結束后,Checker 分析歷史記錄是否正確,是否符合一致性。用戶可以使用 Jepsen 的 knossos 中提供的驗證模型,也可以自己定義符合需求的模型對測試結果進行驗證。同時,還可以在測試中注入錯誤對集群進行干擾測試。

最后根據本次測試所規定的驗證模型對結果進行分析。

如何使用 Jepsen

使用 Jepsen 過程中可能會遇到一些問題,可以參考一下使用 Tips:

  1. 在 Jepsen 框架中,用戶需要在 DB 接口中對自己的數據庫定義下載,安裝,啟動與終止操作。在終止后,可以將 log 文件清除,同時也可以指定 log 的存儲位置,Jepsen 會將其拷貝至 Jepsen 的 log 文件夾中,以便連同 Jepsen 自身的 log 進行分析。

  2. 用戶還需要提供訪問自己數據庫的客戶端,這個客戶端可以是你用 Clojure 實現的,比如 etcd 的 verschlimmbesserung,也可以是 JDBC,等等。然后需要定義 Client 接口,告訴 Jepsen 如何對你的數據庫進行操作。

  3. 在 Checker 中,你可以選擇需要的測試模型,比如,性能測試(checker/perf)將會生成 latency 和整個測試過程的圖表,時間軸(timeline/html)會生成一個記錄著所有操作時間軸的 html 頁面。

  4. 另外一個不可或缺的組件就是在 nemesis 中注入想要測試的錯誤了。網絡分區(nemesis/partition-random-halves)和殺掉數據節點(kill-node)是比較常見的注入錯誤。

  5. 在 Generator 中,用戶可以告知 worker 進程需要生成哪些操作,每一次操作的時間間隔,每一次錯誤注入的時間間隔等等。

用 Jepsen 測試圖數據庫 Nebula Graph

分布式圖數據庫 Nebula Graph 主要由 3 部分組成,分別是 meta 層,graph 層和 storage 層。

我們在使用 Jepsen 對 kv 存儲接口進行的測試中,搭建了一個由 8 個 container 組成的集群:一個 Jepsen 的控制節點,一個 meta 節點,一個 graph 節點,和 5 個 storage 節點,集群由 Docker-compose 啟動。需要注意的是,要建立一個集群的 subnet 網絡,使集群可以連通,另外要安裝 ssh 服務,并為 control node 與 5 個 storage 節點配置免密登入。

測試中使用了 Java 編寫的客戶端程序,生成 jar 包并加入到 Clojure 程序依賴,來對 DB 進行 put,get 和 cas (compare-and-set) 操作。另外 Nebula Graph 的客戶端有自動重試邏輯,當遇到錯誤導致操作失敗時,客戶端會啟用適當的重試機制以盡力確保操作成功。

Nebula-Jepsen 的測試程序目前分為三種常見的測試模型和三種常見的錯誤注入。

Jepsen 測試模型

single-register

模擬一個寄存器,程序并發地對數據庫進行讀寫操作,每次成功的寫入操作都會使寄存器中存儲的值發生變化,然后通過對比每次從數據庫讀出的值是否和寄存器中記錄的值一致,來驗證結果是否滿足線性要求。由于寄存器是單一的,所以在此處我們生成唯一的 key,隨機的 value 進行操作。

multi-register

一個可以存不同鍵的寄存器。和單一寄存器的效果一樣,但此處我們可以使 key 也隨機生成了。

4       :invoke :write  [[:w 9 1]]
4       :ok     :write  [[:w 9 1]]
3       :invoke :read   [[:r 5 nil]]
3       :ok     :read   [[:r 5 3]]
0       :invoke :read   [[:r 7 nil]]
0       :ok     :read   [[:r 7 2]]
0       :invoke :write  [[:w 7 1]]
0       :ok     :write  [[:w 7 1]]
1       :invoke :read   [[:r 1 nil]]
1       :ok     :read   [[:r 1 4]]
0       :invoke :read   [[:r 8 nil]]
0       :ok     :read   [[:r 8 3]]
:nemesis        :info   :start  nil
:nemesis        :info   :start  [:isolated {"n5" #{"n2" "n1" "n4" "n3"}, "n2" #{"n5"}, "n1" #{"n5"}, "n4" #{"n5"}, "n3" #{"n5"}}]
1       :invoke :write  [[:w 4 2]]
1       :ok     :write  [[:w 4 2]]
2       :invoke :read   [[:r 5 nil]]
3       :invoke :write  [[:w 1 2]]
2       :ok     :read   [[:r 5 3]]
3       :ok     :write  [[:w 1 2]]
0       :invoke :read   [[:r 4 nil]]
0       :ok     :read   [[:r 4 2]]
1       :invoke :write  [[:w 6 4]]
1       :ok     :write  [[:w 6 4]]

以上片段是截取的測試中一小部分不同的讀寫操作示例,

其中最左邊的數字是執行這次操作的 worker,也就是進程號。每發起一次操作,標志都是 invoke,接下來一列會指出是 write 還是 read操作,而之后一列的中括號內,則顯示了具體的操作,比如

  • :invoke :read   [[:r 1 nil]]就是讀取 key 為 1 的值,因為是 invoke,操作剛剛開始,還不知道值是什么,所以后面是 nil。

  • :ok     :read   [[:r 1 4]] 中的 ok 則表示操作成功,可以看到讀取到鍵 1 對應的值是 4。

在這個片段中,還可以看到一次 nemesis 被注入的時刻。

  • :nemesis   :info   :start  nil 標志著 nemesis 的開始,后面的的內容 (:isolated ...) 表示了節點 n5 從整個集群中被隔離,無法與其他 DB 節點進行網絡通信。

cas-register

這是一個驗證 CAS 操作的寄存器。除了讀寫操作外,這次我們還加入了隨機生成的 CAS 操作,cas-register 將會對結果進行線性分析。

0        :invoke    :read        nil
0        :ok            :read        0
1        :invoke    :cas        [0 2]
1        :ok            :cas        [0 2]
4        :invoke    :read        nil
4        :ok            :read        2
0        :invoke    :read        nil
0        :ok            :read        2
2        :invoke    :write    0
2        :ok            :write    0
3        :invoke    :cas        [2 2]
:nemesis        :info        :start    nil
0        :invoke    :read        nil
0        :ok            :read        0
1        :invoke    :cas        [1 3]
:nemesis        :info        :start    {"n1" ""}
3        :fail        :cas        [2 2]
1        :fail        :cas        [1 3]
4        :invoke    :read        nil
4        :ok            :read        0

同樣的,在這次測試中,我們采用唯一的鍵值,比如所有寫入和讀取操作都是對鍵 “f” 執行,在顯示上省略了中括號中的鍵,只顯示是什么值。

  • :invoke    :read  nil 表示開始一次讀取 “f” 的值的操作,因為剛開始操作,所以結果是 nil(空)。

  • :ok      :read  0 表示成功讀取到了鍵 “f” 的值為 0。

  • :invoke    :cas  [1 2] 意思是進行 CAS 操作,當讀到的值為 1 時,將值改為 2。

在第二行可以看到,當保存的 value 是 0 時,在第 4 行 cas[0 2] 會將 value 變為 2。在第 14 行當值為 0時,17 行的 cas[2 2] 就失敗了。

第 16 行顯示了 n1 節點被殺掉的操作,第 17、18 行會有兩個 cas 失敗(fail)

Jepsen 錯誤注入

kill-node

Jepsen 的控制節點會在整個測試過程中,多次隨機 kill 某一節點中的數據庫服務而使服務停止。此時集群中就少了一個節點。然后在一定時間后再將該節點的數據庫服務啟動,使之重新加入集群。

partition-random-node

Jepsen 會在測試過程中,多次隨機將某一節點與其他節點網絡隔離,使該節點無法與其他節點通信,其他節點也無法和它通信。然后在一定時間后再恢復這一網絡隔離,使集群恢復原狀。

partition-random-halves

在這種常見的網絡分區情景下,Jepsen 控制節點會將 5 個 DB 節點隨機分成兩部分,一部分為兩個節點,另一部分為三個。一定時間后恢復通信。如下圖所示。

測試結束后

Jepsen 會根據需求對測試結果進行分析,并得出本次測試的結果,可以看到控制臺的輸出,本次測試是通過的。

2020-01-08 03:24:51,742{GMT}    INFO    [jepsen test runner] jepsen.core: {:timeline {:valid? true},
 :linear
 {:valid? true,
  :configs
  ({:model {:value 0},
    :last-op
    {:process 0,
     :type :ok,
     :f :write,
     :value 0,
     :index 597,
     :time 60143184600},
    :pending []}),
  :analyzer :linear,
  :final-paths ()},
 :valid? true}
Everything looks good! ヽ(‘ー`)ノ

自動生成的 timeline.html 文件

Jepsen 在測試執行過程中會自動生成一個名為 timeline.html 文件,以下為本次實踐生成的 timeline.html 文件部分截圖

上面的圖片展示了測試中執行操作的時間軸片段,每個執行塊有對應的執行信息,Jepsen 會將整個時間軸生成一個 HTML 文件。

Jepsen 就是這樣按照順序的歷史操作記錄進行 Linearizability 一致性驗證,這也是 Jepsen 的核心。我們也可以通過這個 HTML 文件來幫助我們溯源錯誤。

Jepsen 生成的性能分析圖

下面是一些 Jepsen 生成的性能分析圖表,本次實踐項目名為「basic-test」各位讀者閱讀時請自行腦補為你項目名。

可以看到,這一張圖表展示了 Nebula Graph 的讀寫操作延時。其中上方灰色的區域是錯誤注入的時段,在本次測試我們注入了隨機 kill node。

而在這一張圖展示了讀寫操作的成功率,我們可以看出,最下方紅色集中突出的地方為出現失敗的地方,這是因為 control node 在殺死節點時終止了某個 partition 的 leader 中的 nebula 服務。集群此時需要重新選舉,在選舉出新的 leader 之后,讀寫操作也恢復到正常了。

通過觀察測試程序運行結果和分析圖表,可以看到 Nebula Graph 完成了本次在單寄存器模型中注入 kill-node 錯誤的測試,讀寫操作延時也均處于正常范圍。

Jepsen 本身也存在一些不足,比如測試無法長時間運行,因為大量數據在校驗階段會造成 Out of Memory。

但在實際場景中,許多 bug 需要長時間的壓力測試、故障模擬才能發現,同時系統的穩定性也需要長時間的運行才能被驗證。但與此同時,在使用 Jepsen 對 Nebula Graph 進行測試的過程中,我們也發現了一些之前沒有遇到過的 Bug,甚至其中一些在使用中可能永遠也不會出現。

目前,我們已經在日常開發過程中使用 Jepsen 對 Nebula Graph 進行測試。Nebula Graph 有代碼更新后,每晚都將編譯好的項目發布在 Docker Hub 中,Nebula-Jepsen 將自動下拉最新的鏡像進行持續測試。

關于Jepsen 測試框架在圖數據庫 Nebula Graph中的實踐分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

若尔盖县| 宣武区| 西乌珠穆沁旗| 六枝特区| 合水县| 横峰县| 封丘县| 二连浩特市| 长岭县| 宁国市| 区。| 昌乐县| 彰武县| 景泰县| 靖西县| 长兴县| 合山市| 丰都县| 麟游县| 务川| 女性| 锦州市| 固安县| 洛南县| 刚察县| 新昌县| 金秀| 珠海市| 济阳县| 太原市| 古蔺县| 阿拉善左旗| 宜兰县| 乐陵市| 台中市| 巴中市| 城步| 漠河县| 高要市| 道真| 闵行区|