Elasticell和Jepsen測試

王磊:分散式系統中的一致性zhuanlan.zhihu.com圖標

上一篇文章,介紹了分散式系統一致性的概念。文章最後問題來了,有沒有現成的工具可以做分散式系統一致性的測試呢?答案是Jepsen。

分散式系統一致性測試,要解決的兩個主要問題:

首先,各種異常測試條件的模擬:

    1. 網路分區、網路抖動
    2. 操作系統/進程 crash
    3. 操作系統時鐘不一致
    4. 某個節點/進程頻繁重啟、延遲過高

採用一些現成的linux工具,可以對這些場景進行手工模擬:

  1. 網路分區 Iptables
  2. 網路抖動 traffic control
  3. 進程crash 、slow: kill -9; kill -S STOP ;kill -S CONT

然而

  • 節點數量很多,工作量大
  • 手工工操作不及時,例如修改系統時間
  • 多個異常條件和邊界條件組合困難
  • 需要抓取日誌各節點日誌

因此,手工模擬的方法,效率太低,很難滿足工程需求。

其次,對讀寫測試結果做分析

  • 確定本次操作是否滿足Linearizability
  • 如果不滿足,找到本次讀寫可能出錯的地方。
  • 測試結果的數據量可能比較大,人工查看日誌顯然效率太低

如何解決以上問題?---Jepsen

Jepsen是一個分散式系統一致性的測試框架,採用編程的方式解決上述兩個問題。

jepsen-io/jepsengithub.com圖標

Jepsen的工作簡單來說做了以下幾個事情:

  1. 部署好一個分散式系統集群,並啟動它
  2. 運行一系列的針對集群讀寫操作,同時周期性的做一些網路分區、啟動進程之類的破壞性操作
  3. 對上一步中的讀寫測試結果做分析,看是否滿足一致性,如果出錯找到可能出錯的地方

對於破壞性測試用例,Jepsen中叫做(nemesis),有一些現成的代碼實現,包括:

  • partition-random-halves 測試節點中隨機選擇兩組節點做分區
  • partition-majorities-ring 每個節點看到的多數派均不相同
  • hammer-time 暫停被測試進程
  • clock-scrambler 隨機調整節點時間

如何使用Jepsen

Jepsen是clojure編寫的,用戶只需要實現幾個介面數,Jepsen就可以把整個測試run起來:

  • db函數
    • 啟動節點
    • 關閉節點
  • client介面
    • 讀操作
    • 寫操作

可以參考下elasticell的Jepsen測試代碼,代碼並不複雜。

對於測試結果的數據分析,需要調用另外一個cloujures工程,knososs(克諾索斯):

jepsen-io/knossosgithub.com圖標

這部分代碼也不麻煩:

對於測試結果,如果發現讀寫有問題,jepsen會報告可能出錯的地方:

我們的Jepsen測試代碼:

deepfabric/elasticellgithub.com圖標

Jepsen測試中的一些困難

  • 實現精細流程式控制制比較困難。比在系統內部發生數據分片或者遷移時候,指定Jepsen觸發網路分區或者進程crash等操作,目前還很困難,Jepsen更像一個黑盒工具。
  • 每次測試之前必須清空數據,否則正確性校驗報錯
  • 結果分析中,如果數據量比較大,會出現OOM。Jepsen和knossos都是Clojure寫的,FP做數據分析,代碼好寫,但內存佔用大,沒太好辦法,建議把JVM的heapMemory調大些。
  • 複雜數據類型的結果分析,需要專門做一些定製開發,例如cockroachdb,其正確性校驗的checker model等均為自己定製,可以參考下面鏈接:

DIY Jepsen Testing CockroachDBwww.cockroachlabs.com圖標CockroachDB beta-20160829jepsen.io圖標

誰在使用Jepsen

  • cockroachdb
  • etcd/zookeeper
  • voltdb
  • nuodb

國內也有不少團隊在使用Jepsen,除了elasticell外,TiDB也在都在使用


推薦閱讀:

怎樣理解王爾德的【談論天氣是無趣人類最後的避難所】這句話?
Linearizability 一致性驗證
談談PhxSQL的設計和實現哲學(下)

TAG:一致性 | 分散式系統 | 分散式一致性 |