GitHub里的MySQL基礎架構自動化測試
作者丨tomkrouper && shlomi-noach
翻譯丨Diwei
MySQL對於GitHub的重要性不言而喻,本文作者從MySQL的備份、自動測試能否成功從備份恢複數據、模擬各種 master 可能掛掉的情況、自動測試 failover 是否正常、自動測試 schema 遷移等幾個方面說明了為何會相信MySQL自動化。以下為譯文。
對於GitHub來說,MySQL的基礎架構是非常重要的組件。MySQL給GitHub.com、GitHub的API、身份驗證等提供服務。每個git請求都或多或少會接觸到MySQL。我們的任務是保持數據的可用性和完整性。即使MySQL集群服務出現意外了,也需要能夠執行一些任務,比如繁重的清理工作、臨時更新、在線模式遷移、集群拓撲重構、池化和負載平衡等等。我們有基礎設施來自動化這些操作。在本文將分享一些例子,說明如何通過持續測試來建立我們對基礎設施的信任。
備份
對數據進行備份是非常重要的。如果還沒有進行備份,那麼這就是一個潛在的問題。Percona Xtrabackup是用來為MySQL資料庫提供完整備份的工具。如果有一些已經確定需要保存的數據,也有一個專門備份數據的伺服器。
除了完整的二進位備份之外,每天還運行幾次邏輯備份。這些備份使工程師能夠獲得最新的數據。有時,他們希望從表中獲得一組完整的數據,這樣他們就可以在跟生產數據量一樣的表上測試索引的更改是否有效,或者從某個時間點查看數據。Hubot允許恢復一張備份的表,當表已經導入好以後,它就會ping給我們。
數據被載入到非生產資料庫,該資料庫可供那些提出恢複數據要求的工程師們訪問。
最後一種進行數據備份的方法是使用延時複製。與其說是一種備份,倒不如說是對數據的一種保障。對於每個生產集群,有一個延遲4小時複製的主機。假如某個查詢沒有運行,我們會在chatops(即一種會話驅動型開發的做法)上運行mysql panic。這將導致所有的延遲複製立即停止複製,然後「呼叫」資料庫管理員。
雖然說備份這個功能設計的很棒,但是如果一些未知或未捕獲的錯誤導致備份沒有成功,它們就會變得毫無價值。使用腳本恢復備份的好處就是它允許我們通過cron(是一個linux下的定時執行工具,可以在無需人工干預的情況下運行作業)自動驗證備份文件是否有效。我們為每個集群都設置了一台專用主機,這台主機就是用來恢復最新的備份數據。這樣可以確保備份正常運行,並且我們能夠從備份中檢索數據。
根據數據集大小會選擇每天進行幾次恢復。恢復後的伺服器會按照預期加入到複製流中,並能夠趕上複製。這種做法不僅僅是在測試備份文件是否可恢復,而且還可以測試需要識別的時間點是否準確。如果恢復過程中出現問題,我們會收到通知。
還追蹤恢復的時間,所以我們很清楚在緊急情況下建立新的副本或恢復需要多長時間。
以下是自動恢復過程中Hubot編寫的一些輸出信息。
使用備份是為了給現有的MySQL伺服器集添加一個新的副本。我們將構建一個新的伺服器,一旦被告知它已經準備好,我們就可以開始恢復該特定集群的最新備份。有一個腳本可以運行所有的恢復命令,否則我們將不得不手工操作備份。我們的自動恢復系統實際上使用了相同的腳本。這大大簡化了系統的構建過程,並允許我們使用聊天命令行的模式來啟動和運行主機。下面顯示的是在運行聊天命令行模式的數據恢復方法:
備份失敗
使用Orchestrator (使你能夠在工作環境中自動創建、監視和部署資源)為使用者執行自動化故障切換。期望Orchestrator可以正確檢測master是否出現故障,然後可以指定副本進行升級,在所指定的副本下修復拓撲以後再升級。希望VIPs能夠改變,池可以改變,客戶端可以重新連接,puppet可以運行必要的組件等等。故障切換是一個複雜的任務,涉及到基礎架構的許多方面。
為了建立對故障切換的信任,建立了一個類生產的測試集群,然後讓它不斷的崩潰以觀察故障切換功能。
類生產環境與生產環境在很多方面的設置是完全相同的:硬體類型,操作系統,MySQL版本,網路環境,VIP,puppet配置,haproxy設置等。唯一不同之處在於測試集群不發送/接收生產流量。
在測試集群上模擬寫入負載,同時避免複製延遲。寫入負載不會超荷,但是有一些查詢,這些查詢是有意在相同的數據集中寫入的。這在正常的時期作用並不明顯,但事實證明是有用的,我們將會簡要描述。
測試集群有三個數據中心的代表伺服器。希望故障轉移可以在同一數據中心內的伺服器能夠在對方時效時自動接替彼此的工作。希望能夠在這樣的約束下儘可能多地搶救出儘可能多的複製品,這些複製品能夠儘可能的適用。orchestrator對拓撲結構沒有先前的假設,它只能對出故障時的狀態做出反應。
然而,我們有興趣為故障轉移創建複雜而多變的場景。我們的故障轉移測試腳本為故障轉移準備了理由:
它識別現有的master;
它重構了拓撲結構,使所有三個數據中心的代表成為主控。不同的DC具有不同的網路延遲,並且預期會在不同的時間對主機的崩潰做出反應;
它選擇一個解決崩潰方法。 我們選擇殺掉master(kill -9)或網路劃分它:iptables -j REJECT(nice-ish)或iptables -j DROP(無響應)。
腳本繼續通過選擇的方法使master崩潰,並等待orchestrator可靠地檢測到崩潰並執行故障轉移。雖然我們期望檢測和升級在30秒內完成,但腳本並不會如你所願,它在查找故障切換結果之前浪費掉一段指定的時間。比如:
檢查一個新的(不同的)主人是否到位;
集群中有大量的副本;
master是可改變的;
對master的寫入在副本上可見;
更新內部服務發現條目(新主人的身份如預期;舊主人已刪除);
其他內部檢查。
這些測試確認故障轉移是成功的,不僅是MySQL-wisee,而且是在我們更大的基礎架構範圍內。人們已經假設了一個VIP;具體的服務已經開始;信息到達了應該去的地方。
該腳本進一步恢復了失敗的伺服器:
從備份中恢復它,從而隱式地測試我們的備份/恢復過程
驗證伺服器配置如預期的那樣(伺服器不再相信它是主伺服器)
將其返回到複製集群,期望找到在主伺服器上寫入的數據
考慮以下預定的可視化故障轉移測試:從一個運行良好的集群,看到問題在一些副本,診斷主(7136)死了,選擇一個伺服器來促進(a79d),重構拓撲低於伺服器,為促進它(故障轉移成功),恢復死去的主人,將它們轉化為集群。
測試失敗看起來像什麼呢
測試腳本使用了一種stop-the-world的方法。故障轉移組件中不管哪個環節出現問題,在管理員解決問題之前,整個過程都是失敗的,而且後面的自動化測試也是無法執行的。當然我們會收到提醒,然後檢查狀態和日誌。
測試腳本在以下環節中可能會失敗:出現了意外的檢測;故障轉移期間;在備份/恢復問題上;太多伺服器出現宕機;在故障轉移後的意外配置上等等。
我們需要確保orchestrator正確地連接到伺服器。這就是之前說的寫入負載會起作用的地方:如果設置不正確,複製很容易被破壞。我們會得到DUPLICATE KEY或其他錯誤,以表示出了問題。
這一點尤其重要,所以我們對orchestrator進行了改進,引入了新的行為,並允許我們在一個安全的環境中測試這些更改。
混沌測試即將到來
上面演示的測試過程能夠捕獲(並已捕獲)基礎架構的許多問題。但這就夠了嗎?
在生產環境中總會有各種各樣的問題。關於這些特定的測試方法,它不適用於我們的生產集群。它們不共享相同的流量和流量操作,也沒有相同的伺服器集。失敗的類型可能會有所不同。
正在為生產集群設計混沌測試。 混沌測試將會在我們的生產中,但是按照預期的時間表和充分控制的方式來破壞碎片。混沌測試引入了對恢復機制的更高級別的信任,並影響(因此測試)更大的基礎架構和應用程序。
這是一項微妙的工作:儘管我們承認需要進行混沌測試,但我們也希望避免對服務造成不必要的影響。不同的測試在風險級別和影響方面會有所不同,我們將努力確保服務的可用性。
Schema遷移
我們使用gh-ost從而將生產的schema進行遷移。gh-ost非常穩定,但是現在正在增加或者計劃增加一些新的主要的功能,因此現在也處於開發當中。
gh-ost通過將數據複製到ghost表中,將二進位日誌所攔截的正在進行的更改應用到ghost表上,即使原始表被寫入到這個表中,也可以將表移到表上。然後,它將ghost表替換為原來的表。在遷移完成時,GitHub將繼續使用由gh-ost生成並填充的表。
這一次,幾乎所有的GitHub MySQL數據都是由gh-ost重新創建的,而且大部分都是重複的。我們必須高度信任gh-ost,讓它一次又一次地篡改我們的數據,即使是在開發過程中。下面是我們如何獲得信任的方法。
gh-ost提供了一個測試生產能力。它支持在副本上運行一個遷移,就像它在主伺服器上運行的方式一樣:gh-ost將連接到副本,並將其視為主伺服器。它將以與實際主遷移相同的方式解析它的二進位日誌。但是,它將複製行並將binlog事件應用到副本中,並避免將寫入寫入到主伺服器上。
我們在生產中運行了專門的專用副本。這些副本不服務於生產流量。每個這樣的副本都檢索當前的生產表列表,並以隨機的順序迭代它們。一個接一個地選擇一個表,並在該表上執行一個複製遷移。遷移實際上並沒有修改表結構,而是運行一個簡單的引擎=InnoDB。即使在生產中使用表時,測試也會運行遷移,從而複製實際的生產數據,並在二進位日誌中應用真正的生產流量。
這些遷移可以被審核。下面是我們如何從聊天中檢查運行測試的狀態:
當一個測試遷移完成了對錶數據的複製時,它停止複製並執行剪切操作,替換原來的表,用ghost表替換原來的表,然後交換回來。我們對實際替換數據不感興趣。取而代之的是原始表和ghost表,兩者都應該是相同的。我們通過檢查這兩個表的整個表數據來驗證這一點。
一個測試可以完成:
成功:一切都很順利,校驗和也一樣。我們希望看到這一點。
失敗:執行的問題。由於遷移過程被殺死、複製問題等等,這種情況有時會發生,而且通常與ghost本身無關。
校驗和失敗:表數據不一致。對於經過測試的分支,這需要修復。對於正在進行的主分支測試,這將意味著立即停止生產遷移。我們沒有得到後者。
測試結果被審計,發送到機器人聊天室,作為事件發送給我們的度量系統。下面的圖中的每一條垂直線代表一個成功的遷移測試:
連續運行這些測試。如果出現故障,我們會收到警報通知。當然,我們也可以去機器人聊天室看看發生了什麼。
新版本測試
我們一直在改善gh-ost,我們的開發流程都是基於git的分支,最後再通過pull請求進行合併。
提交的 gh-ost pull請求通過持續集成(CI)進行基本的編譯和單元測試。從技術上講,該公司在技術上有資格合併,但更有趣的是,它有資格通過天堂進行部署。作為我們基礎架構中的敏感組件,我們需要在合併成主之前,將gh-ost分支部署到密集的測試中。
有些PRs是小的,不影響數據本身。對狀態消息、交互命令等的更改對ghost應用程序的影響較小,其他一些則對遷移邏輯和操作造成了顯著的變化。我們將嚴格地測試這些數據,在我們的生產表艦隊中運行,直到滿足這些更改不會造成數據損壞威脅。
結論
通過測試,我們就更想新機器的運作額。通過在生產中做這些自動化測試,我們可以不斷的得到一切都如預期的那樣運行的確認信息。隨著基礎架構的繼續開發,我們也會通過調整測試從而滿足最新的調整。
在沒有測試的情況下,生產總是令人驚訝的。我們對生產環境的測試越多,我們對應用程序的期望和基礎設施的能力就會得到更多的投入。
點擊展開全文


※開發者應該知道的代碼審查工具,杜絕代碼bug
※九張圖帶你了解全宇宙最神秘的團體——程序員
※AI 產學研大集結,2017中國人工智慧大會將於明日正式召開
※目前最值得學習的9種前沿的開發語言,可能有一天你會發現……
※如何快速全面建立自己的大數據知識體系?
TAG:CSDN |
※Unity Labs:AutoLOD自動化性能提升的實驗
※基於Testbench的FPGA實物自動化測試環境設計
※自動化系統再次繞過Google reCAPTCHA
※JMeter+Ant+Jenkins+SVN 介面自動化環境搭建
※DXC Technology推出DXC Bionix?,以大規模提供自動化IT服務
※Burp Suite二十節:使用Burp,Sqlmap進行自動化SQL注入滲透測試
※GitHub Actions 集成 CI/CD 功能,推進開發編譯測試部署流程自動化
※GitHub Actions 集成CI/CD功能,推進開發編譯測試部署流程自動化
※Jmeter+Ant+Jenkins介面自動化測試框架搭建for Windows
※使用 Selenium 自動化 Web 瀏覽器
※Linux操作系統已擁有自動化的Spectre/Meltdown檢查器
※AI、自動化為硬核:更技術范兒的DJI RoboMaster機器人挑戰賽
※AI、自動化為硬核:更技術范兒的 DJI RoboMaster 機器人挑戰賽
※Linux Shell互動式自動化運維程序
※NI推出InstrumentStudio軟體 簡化了自動化測試系統的開發和調試
※Fuzz自動化Bypass軟WAF姿勢
※BigQuery現支持Terraform以自動化數據集部署
※Canonical開發實現Ubuntu Server自動化安裝的新手段
※Red Hat正式發布OpenShift 4 專註可擴展性和自動化
※Box收購自動化初創公司Progressly 提高企業生產力