Jepsen對etcd 3.4.3測試的最新結果
- 2020 年 2 月 20 日
- 筆記
作者:Xiang Li
Jepsen對etcd 3.4.3進行了測試和分析,得到了良好的結果和有用的反饋。
etcd設計的一個關鍵部分是跨分佈式鍵值存儲的強一致性保證。Kubernetes、Rook、OpenStack和無數其他重要的軟件項目都依賴於etcd,部分原因是etcd項目注重可靠性和正確性。
多年來,etcd團隊在構建測試和混沌工程框架方面付出了巨大的努力。我們覺得我們已經改進了我們的一致性,並要求Jepsen進行驗證。
https://coreos.com/blog/testing-distributed-systems-in-go.html
https://coreos.com/blog/new-functional-testing-in-etcd.html
Jepsen是測試開源分佈式系統以檢查它們是否滿足其一致性保證的領先公司。他們首次測試etcd是在0.4.1版本(五年前),從那時起我們就一直使用這些發現來改進我們的一致性。在這篇博文中,我們分享了etcd v3.4.3的Jepsen分析的總體積極結果,以及我們解決分析中發現的問題的計劃。
Jepsen測試工作的資金由託管etcd的CNCF提供。
有哪些進行得很順利
在Jepsen針對etcd集群創建的眾多故障案例中,它繼續按設計運行。從分析中,Jepsen的作者說:
- "etcd 3.4.3 lived up to its claims for key-value operations: we observed nothing but strict-serializable consistency for reads, writes, and even multi-key transactions, during process pauses, crashes, clock skew, network partitions, and membership changes. Strict serializable behavior was the default for key-value operations."
- "Watches appear correct, at least over single keys. So long as compaction does not destroy historical data while a watch isn't running, watches appear to deliver every update to a key in order."
由於Jepsen從不「通過」軟件,而是報告不存在禁止的問題,因此這是一個很好的結果。一般來說,它比迄今為止測試的其他分佈式數據庫要好得多。
https://jepsen.io/analyses
我們認為,有兩個因素促成了這個積極的嚴格分析結果:
1. 一個簡單的核心
一個簡單的解決方案通常會產生一個健壯的系統。例如,etcd的Raft實現是開源中最簡單的實現之一。它關注於Raft的核心狀態機,避免了核心庫中的wall-time和I/O處理。在它的API中,etcd支持多鍵事務,但是採用了簡單的事務模型來保持系統更容易理解。
2. 嚴格的測試實踐
在etcd開發周期的早期,我們設定了一個目標,在諸如Raft和MVCC存儲引擎等核心組件上實現80%和90的單元測試線覆蓋率。隨着項目的進展,我們努力通過引入故障點來確保核心組件的邏輯路徑覆蓋。為了滿足時間、操作系統調度和異步網絡I/ OS的隨機性,我們還開發了連續集成測試,24×7運行,嘗試在運行的系統上以單元測試無法做到的方式產生問題。這些試驗顯著提高了etcd的質量。
https://github.com/etcd-io/etcd/issues/1467
確定的問題
當然,沒有哪個系統在沒有報告某些可能更好的地方的情況下進行Jepsen測試。etcd有一些:
鎖的問題
在測試期間發現了一個鎖實現問題,其中etcd未能在掛起的鎖API調用返回之前檢查鎖的所有權。
在etcd中,鎖獲取者與會話相關聯;獲取者持有鎖,直到會話結束。當第一次嘗試獲取鎖時,它可能被其他人持有。在這種情況下,etcd服務器將獲取者放入一個隊列,它必須在隊列中等待,直到其他鎖持有者釋放鎖。問題是,獲取者的交易可能會在這段等待時間內終止。這種提前過期的結果是etcd服務器必須在返回API調用之前再次檢查會話的存在性。
文檔的問題
Jepsen分析不僅包括軟件正確性,還驗證了文檔聲明。Jepsen的作者發現了etcd的文檔問題和誤導性用例。以前的etcd文檔中關於一致性(consistency)和隔離(isolation)的內容不清楚,可能會引起混淆。
我們的文檔描述了基於Wikipedia定義的一致性模型,這也是一些etcd工程師在大學裏學到的分類。它還將隔離級別與一致性級別分開,因為對於如何將兩者定義在一起沒有普遍的共識。
Jepsen的作者建議etcd文檔採用最初由Herlihy和Wing發表的線性化論文中定義的術語「嚴格的串行化(strict serializability)」。在閱讀了關於其他開源項目的文檔,以及聽取用戶的反饋之後,etcd團隊同意Jepsen作者的觀點,即建議的模型和術語更清晰、更容易理解。
接下來,lock API用例示例具有誤導性,可能會導致運行時問題。
與任何其他分佈式鎖系統一樣,etcd鎖提供的保證與本地線程級鎖不同。具體來說,etcd鎖只在etcd自己的密鑰空間和帶有修訂檢查的事務中安全地保證互斥。當訪問依賴於時間的外部資源時,它提供了較弱的保證。使用分佈式鎖很難防止死鎖和鎖定失效,因為分佈式鎖不能保護同一進程甚至同一機器中的資源。為了解決這個問題,分佈式鎖通常依賴於租約和心跳機制來檢測斷開連接的鎖持有者並使鎖失效。當一個鎖持有者斷開連接或在沒有使用修訂檢查(etcd中的隔離令牌實現)的情況下暫停時,它可能會與新的鎖持有者同時訪問受保護的資源。更多細節可以在Kleppmann的博客中找到。
https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html
etcd鎖文檔沒有指出這種區別,並提供了使用鎖的不準確示例。我們同意Jepsen團隊的觀點,即問題必須得到解決,etcd用戶應該被告知準確的聲明。
問題的處理
etcd團隊和Jepsen團隊正在處理上面提到的所有問題。以下是問題和修復的列表。我們感謝社區對這些問題的反饋,並幫助etcd項目變得更好。

未來
Jepsen分析不是一次性的工作。在分析過程中,Jepsen團隊專門為etcd項目建立了一個廣泛的測試框架。它還使etcd團隊和社區能夠隨時運行這些測試並在將來捕獲問題。
我們很樂意看到etcd社區中有人將etcd Jepsen測試直接集成到現有的etcd發行流水線中。我們希望確保所有etcd的未來版本都通過了Jepsen測試。
除了Jepsen分析之外,etcd社區總是歡迎與正確性和可靠性相關的貢獻。我們對這次測試的結果感到興奮,並將保持警惕,同時建立一個良好的工程和正確的產品。
要了解更多,請閱讀Jepsen給etcd 3.4.3的完整報告。
https://jepsen.io/analyses/etcd-3.4.3