距離我們上次發布 Jepsen 更新已經有一段時間了,我們知道很多人都渴望聽到最新消息。這個新部落格提供了最新的更新,並分享了有關其他內部構建的彈性和一致性測試框架的信息,這些框架遠遠超出了 Jepsen 的範圍。
彈性和一致性測試不僅僅是我們工程團隊的另一組指標。我們說 YugabyteDB 是可擴展且永不失敗的分散式 Postgres,
我們透過建造和使用最先進的測試框架來證明這一點。
本部落格中共享的框架旨在透過模擬我們希望沒有人在生產中遇到的故障來嘗試關閉資料庫。看到 YugabyteDB 甚至能夠容忍最不可能的重大事件,這讓我們相信我們的開源用戶和客戶正在獲得最可靠的 Postgres 分散式版本。
下面我們從 Jepsen 開始,然後深入研究我們 巴拉圭 電話號碼庫 的混沌測試框架。最後我們討論如何測試作業系統、硬體和各種部署環境的彈性。
傑普森測試
首先,我們要感謝 Jepsen 及其敬業的所有者 Kyle Kingsbury,感謝他們在發展和完善這個寶貴的測試框架方面所做的持續努力。
自 2019 年以來,我們的 QA 和工程團隊一直在努力升級我們的測試環境,以利用 Jepsen 的最新增強功能。我們顯著擴展了我們的測試套件,添加了新場景,並透過突破分散式資料庫測試界限的功能來改進現有場景。
擴展場景:我們引入了bank-contention場景來解決原始bank工作負載有限的INSERT/DELETE覆蓋範圍。如下圖所示,這個擴展場景使用了兩個鍵空間:一個用於更新,另一個用於插入/刪除操作。我們也透過合併 READ COMMITTED 和 REPEATABLE READ 隔離等級、地理分割區以及讀取作業的隨機
行級鎖定來增強追加場景。
滾動段鍵
新功能覆蓋範圍:我們的 Jepsen 測試現在包括廣泛的 YugabyteDB 功能,包括:
只讀副本:使用唯讀副本將跟隨者讀取操作整合到銀行工作負載中,以進行全面的讀取操作測試。
Wait-On-Conflict:在bank和append測試中加入了同時控制模式,模擬真實的同時場景。
快照(可重複讀取)和已提交讀取:將這些隔離等級合併到附加測試中(感謝elle),確保穩健的隔離等級測試。
跨地理交易:擴展了附加測試套件以涵蓋地理分佈的交易。
軟體時鐘偏差:使用 gflag 在重新啟動時隨機引入時鐘偏差,模擬現實世界的時鐘同步挑戰。
例如,下圖顯示了 yb-master 和 yb-tserver 重新啟動的時間軸和測試;每次重新啟動都會將
time_source gflag 變更為隨機值。
使用 yb-master 和 yb-tserver 進行時間軸和測試
託管:在 YSQL 測試中隨機啟動託管功能,增加了另一層複雜性和真實性。
這只是我們正在進行的 Jepsen 旅程的一個縮影。查看我們的技術文件以了解有關各種測試場景的更多資訊。
擁抱混沌
雖然 Jepsen 為驗證事務一致性提供了寶貴的基礎,但真正的分散式事務資料庫需要更廣泛的測試方法。
效能、功能,尤其是混亂條件下的復原能力至關重要,尤其是在分散式系統的世界中。這就是為什麼我們超越了 Jepsen 框架,將混沌工程作為我們尋求建立最具彈性的分散式 PostgreSQL 資料庫的核心原則。
我們超越 Jepsen 的旅程始於我們意識到,我們需要將 YugabyteDB 推向其絕對極限,並模擬比標準 Jepsen 場景通常涵蓋的更廣泛的故障。這促使我們開發了一個專門的混沌測試框架,將各種受 Jepsen 啟發的故障直接注入到我們的 YugabyteDB 叢集中。
這個框架現在已經深度融入我們的開 wix 定價:哪種方案適合我的業務? 發流程中。在每個新功能到達我們的用戶之前,我們都會對其進行嚴格的混沌測試。
讓我們回顧一下我們的混沌測試框架涵蓋的一些領域。
額外的事務一致性檢查
即使在事務一致性領域內,我們也認為有必要超越標準的 Jepsen 銀行工作負載。
此工作負載是一個簡單但功能強大的工具,用於驗證交易一致性,預設僅使用更新操作。然而,這留下了覆蓋範圍的空白,我們的目標是改善這一空白。為了解決這個問題,我們顯著增加了工作量:
多表工作負載:認識到現實世界的應用程式很少單獨對單一表進行操作,我們引入了跨具有多個索引的多個表的工作負載。這為我們的測試增加了一層非常需要的複雜性,讓我們能夠發現不同表之間的交互作用可能引起的並發問題。
滾動段鍵:我們實作了滾動段鍵策略,而不是只專注在更新和單獨的插入/刪除鍵空間。如下圖所示,「刪除」針對資料集開頭的鍵,而「插入」則在末尾新增鍵。這不僅簡化了調試,而且消除了記憶體中驗證的需要。這簡化了我們的測試設置,並透過直接檢查儲存層級的資料完整性來提供額外的驗證層。
銀行爭用的擴展場景
行級鎖:為了模擬高爭用環境的複雜性,我們將行級鎖合併到我們的測試場景中。透過模擬行級鎖定,我們可以有效地識別實際部署中可能發生的潛在死鎖和其他並發問題。
為了向您展示不同資料類型覆蓋範圍的工作原理,以下是一些用於檢查餘額的 CREATE TABLE 和 SELECT 語句範例:
雲端混沌測試和其他部署
我們不僅僅在原始、孤立的環境中進行測試。我們的混沌測試涵蓋各種雲端平台和 Kubernetes 設置,反映了我們用戶所依賴的不同部署。
當我們說混亂時,我們是認真的!以下是我們造成的浩劫的一瞥:
雲端 API 混亂:我們利用雲端 API(例如 AWS 提供的 API)的強大功能來觸發一系列中斷,包括節點重新啟動、意外關閉和磁碟區分離。
YugabyteDB 特定的混沌:我們透過將混沌直接注入 YugabyteDB 的核心來超越模擬外部故障。使用 yb-admin 等工具,我們在 yb-master 和 yb-tserver 流程等關鍵元件中引入有針對性的故障,嚴格測試其復原機制並確保資料庫能夠承受內部動盪。
作業系統級破壞:我們模擬了各種現實 台灣數據 世界的基礎設施問題,包括時脈選通、網路分區、DNS 故障、網路速度減慢和儲存中斷,確保 YugabyteDB 能夠經受住經常破壞生產環境的風暴。
Stress-ng Torture:我們透過使用stress-ng來讓記憶體、CPU、網路、I/O作業和作業系統調度程式過載,從而突破了硬體和軟體的極限。這使我們能夠發現瓶頸並確保 YugabyteDB 可以輕鬆處理極端的資源爭用。
讓我們簡要地示範一下我們的故障注入器程式碼在實務上是如何運作的。復仇者隨機決定調用和恢復的時間間隔。通常,呼叫和復原涉及一行程式碼,觸發現有 API 或執行遠端 SSH 命令。
在下圖中,您可以觀察測試期間組合的復仇者行為。
聯合復仇行為
簡單的 API,強大的見解
我們的混沌測試框架建立在「簡單易用,洞察力強大」的原則之上。我們的 Nemesis API 讓注入失敗和監控資料庫復原變得簡單。大多數測試依賴常見故障場景的預定義設置,從而在不犧牲深度或嚴格性的情況下簡化測試過程。
內建檢查和驗證確保測試可靠性,並且我們遵守嚴格的「無崩潰或致命錯誤」政策。資料完整性是基礎,因此我們超越了一般檢查,結合了特定於資料的驗證,以確保即使在極端混亂的情況下,資料也保持一致和準確。
讓我們用另一個例子來說明這一點:平板電腦分裂測驗。
在我們的壓力場景中,我們不僅啟用平板電腦分割;還啟用平板電腦分割。我們將系統推向極限,迫使幾乎每個插入都觸發分裂。我們不止於此。正如下面的程式碼片段所示,我們同時注入節點重新啟動、網路減速,並使用「大鍵」標誌將某些 varchar 列擴展到其正常大小的 100 倍以上,並使用偽隨機但確定的資料。這為我們的資料庫創造了一場完美的風暴,幫助我們發現平板電腦分割邏輯中最微妙的邊緣情況。
在這種情況下,我們的資料驗證方法的基石是偽隨機資料的利用。
下面的程式碼顯示表中的每一行都可以使用其行鍵號碼和預先定義的 UUID 進行重建。乍一看這似乎是隨機的,但它完全是確定性的,使我們能夠在徹底的數據驗證上投入大量資金,確保每一位數據的完整性,即使在最激烈的分裂和模擬故障下也是如此。