Elasticell和Jepsen測試
02-12
王磊:分散式系統中的一致性
推薦閱讀:
上一篇文章,介紹了分散式系統一致性的概念。文章最後問題來了,有沒有現成的工具可以做分散式系統一致性的測試呢?答案是Jepsen。
分散式系統一致性測試,要解決的兩個主要問題:
首先,各種異常測試條件的模擬:
- 網路分區、網路抖動
- 操作系統/進程 crash
- 操作系統時鐘不一致
- 某個節點/進程頻繁重啟、延遲過高
採用一些現成的linux工具,可以對這些場景進行手工模擬:
- 網路分區 Iptables
- 網路抖動 traffic control
- 進程crash 、slow: kill -9; kill -S STOP ;kill -S CONT
然而
- 節點數量很多,工作量大
- 手工工操作不及時,例如修改系統時間
- 多個異常條件和邊界條件組合困難
- 需要抓取日誌各節點日誌
因此,手工模擬的方法,效率太低,很難滿足工程需求。
其次,對讀寫測試結果做分析
- 確定本次操作是否滿足Linearizability
- 如果不滿足,找到本次讀寫可能出錯的地方。
- 測試結果的數據量可能比較大,人工查看日誌顯然效率太低
如何解決以上問題?---Jepsen
Jepsen是一個分散式系統一致性的測試框架,採用編程的方式解決上述兩個問題。
jepsen-io/jepsenJepsen的工作簡單來說做了以下幾個事情:
- 部署好一個分散式系統集群,並啟動它
- 運行一系列的針對集群讀寫操作,同時周期性的做一些網路分區、啟動進程之類的破壞性操作
- 對上一步中的讀寫測試結果做分析,看是否滿足一致性,如果出錯找到可能出錯的地方
對於破壞性測試用例,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/knossos
這部分代碼也不麻煩:
對於測試結果,如果發現讀寫有問題,jepsen會報告可能出錯的地方:
我們的Jepsen測試代碼:
deepfabric/elasticell
Jepsen測試中的一些困難
- 實現精細流程式控制制比較困難。比在系統內部發生數據分片或者遷移時候,指定Jepsen觸發網路分區或者進程crash等操作,目前還很困難,Jepsen更像一個黑盒工具。
- 每次測試之前必須清空數據,否則正確性校驗報錯
- 結果分析中,如果數據量比較大,會出現OOM。Jepsen和knossos都是Clojure寫的,FP做數據分析,代碼好寫,但內存佔用大,沒太好辦法,建議把JVM的heapMemory調大些。
- 複雜數據類型的結果分析,需要專門做一些定製開發,例如cockroachdb,其正確性校驗的checker model等均為自己定製,可以參考下面鏈接:
DIY Jepsen Testing CockroachDBCockroachDB beta-20160829
誰在使用Jepsen
- cockroachdb
- etcd/zookeeper
- voltdb
- nuodb
國內也有不少團隊在使用Jepsen,除了elasticell外,TiDB也在都在使用
推薦閱讀:
※怎樣理解王爾德的【談論天氣是無趣人類最後的避難所】這句話?
※Linearizability 一致性驗證
※談談PhxSQL的設計和實現哲學(下)