PagerDuty是一家新興的互聯網創業公司,它是一款能夠在伺服器出問題是發送提醒的產品,包括螢幕顯示、撥打電話、短信通知、電郵通知等。 目前AdMob、37Signals、StackOverflow、Instagram等均採用了PagerDuty作為消息通知以及突發事件處理工具。 本文作者Doug Barth分享了PagerDuty是如何成功地把現有系統MySQL遷移至XtraDB集群,以及在這一過程中遇到的利與弊。
在半年前,PagerDuty公司成功地把現有系統從MySQL遷移至XtraDB集群,並在其上運行亞馬遜EC2。
舊系統組態分析
從配置上看,這是一個非常典型的MySQL環境:
一對Percona伺服器負責對一個DRBD捲進行資料寫入。
以主副EBS雙機對DRBD捲進行備份。
設立兩個同步複製資料庫,當主伺服器出現問題時,能把業務系統無縫轉移到次伺服器。
配置一系列非同步複製機,以應對重大災難、緊急備份、突發變更維護。
存在的問題
兢兢業業的舊系統服務多年後,面對日益突出的可靠性問題,開始顯現出力不從心了。 此外,每次進行主伺服器切換,無疑於是一場悲劇:要進行DRBD主機切換,首先得在主伺服器上中斷MySQL,離線DRBD卷,把從伺服器狀態變更為主伺服器,重新載入DRBD,最後重啟MySQL。 而這一整套過程會導致服務中斷,因為MySQL在由中斷到重啟的過程中,我們設置了一個冷卻緩衝集區,在系統服務重回正軌前這個冷卻機制需要時間預熱。
我們嘗試通過Percona的緩衝集區恢復(buffer-pool-restore)功能來減少停機時間,但這相對於我們體型龐大的緩衝集區來說如同蚍蜉撼樹。 同時該功能會增加額外的系統資源開銷。 還有個問題是,一旦發生意外的主伺服器切換,非同步從伺服器將停止運作,必須手動重啟。
擁抱XtraDB集群的原因
XtraDB集群的特色:相校于之前的雙機系統,集群中採用的是三機同時運作,兩兩進行同步備份。 因此連接切換時間大為減少。
支援多主伺服器同時線上,每個主伺服器擁有一個熱緩衝集區。 非同步從伺服器可以選擇任何節點作為主機,節點間的轉移不會中斷備份複製進程。
自動化的節點機制與我們目前的自動化系統配合良好。 配置新節點後,我們只需提交一個節點位址,新節點將會自動收到一個資料備份集,同步資料後會載入到主伺服器群中。
前期準備
將XtraDB集群接入現行系統,需要進行一定的前期準備。 部分是簡單的MySQL微調,其餘的是一些基礎化的操作。
在MySQL上的操作:
確保只在InnoDB資料表中設置主鍵。
確保不使用query cache(查詢緩存),由於cluster不支援。
複製方式由基於語句的方式變更為基於行的方式。
除上述MySQL端的操作,為了能在DRBD伺服器上進行獨立的測試,應用系統端需要進行如下的變更:
採用分散式鎖機制,由於MySQL採用的是從本地到集群節點的,例如:執行SELECT FOR UPDATE語句。
用Zookeeper鎖替換MySQL鎖。
為了檢驗所有寫入的資料能在所有節點上進行資料同步,我們對作業邏輯作出變更,以大量小規模資料處理代替一次性大規模資料處理。
模式變更的選擇
在XtraDB集群中進行模式變動是牽一髮而動全身的。 在集群有兩種實現方式,一種是total order isolation (TOI,總序分離式),另外一種是rolling schema upgrade (RSU,滾動模式升級)。
在RSU模式下,允許單獨地對節點進行更新。 當執行DDL語句時,按序同步各個節點,執行完畢後再重新加入集群。 但是這個功能會招致不穩定性,同時資料的大量刷新動作引起的系統問題是不可避免的,由於RSU需要等待DDL語句執行完畢才能進行緩存刷新。
相比之下,TOI的更新操作是一次性同步所有節點,阻斷集群通信直到更新完成。 我們衡量一番後,決定採用TOI模式。 由於系統停機時間較短,所以這次沒有對集群進行阻斷。
遷移過程
首先,我們在現系統中建立一個集群作為現DRBD資料庫的一個從屬。 當該從屬資料庫接收到所有寫入操作時,我們可以進行壓力測試,看看它的承載能力如何;同時會進行相關資料收集和分析。
在進行一系列相關基準測試後,我們發現了兩點技術細節是能夠説明實現遷移前後的系統性能趨於一致:
把innodb_flush_log_at_trx_commit的值設為0或2,可以獲得最優寫入性能。 由於所有變更都是被覆制到3個節點的,即使出現失效情況都不會出現資料丟失情況。
innodb_log_file_size的值需要設置成較大數值,我們將其設置為1GB。
進行一番測試後,XtraDB集群的各項指標令人滿意,我們接下來開始著手進行實際切換。
首先把所有測試環境下的配置進行備份。 因為一旦cluster出現宕機,我們可以快速恢復其至一個單一節點cluster。 我們編寫了具體的操作程式以及進行了相關壓力測試。
在對現有系統的兩個DRBD伺服器進行從屬伺服器設置後,我們還設置了其餘伺服器的從屬設置(例如:災害復原,備份等)。 一切就緒後,我們執行了一次常規的從屬升級操作把系統切換到新環境中。
切換前後的架構變化如下圖所示:
切換後的優點分析
對正在運行的cluster進行重啟和更新時,成功避免了之前造成的通信中斷影響。 成功以TOI模式(pt-online-schema-change)進行模式變更。 寫入衝突處理能力得到優化提升。 當發現一個衝突後,XtraDB Cluster會返回一個鎖死錯誤資訊,在以TOI模式執行DDL語句時同樣可觸發該錯誤資訊返回。 之後,衝突錯誤會導致應用程式伺服器返回一個503錯誤,而我們的負載平衡層設置會捕獲該錯誤,隨後會嘗試在另外的伺服器上重新遞交寫入請求。
切換後的缺點分析
部分cluster的關鍵狀態計數器是按狀態改變的,例如在執行顯示全域狀態指令後(SHOW GLOBAL STATUS),其值會重設為0。 這樣會造成很難根據計數器來進行重要的狀態監控,例如流控制,因為其值的頻繁變更會造成無法準確監控系統的狀態(在使用XtraDB Cluster 5.6的Galera 3.x系統中,該問題已得到解決)。 當一寫入操作衝突發生時,MySQL動態記錄配接器會忽略來自交互語句拋出的異常。
對於系統冷卻預熱問題仍待進一步改進。 目前,我們的應用程式伺服器是連接到一個本地的HAproxy實例,該實例會把自身的連接資料發送給一個cluster節點。 在執行計畫維護任務時,我們只能緩慢地把資料推入另一個節點,以在其能完全承載整個系統負荷前進行緩衝集區的預熱。 在將來,我們會按計劃完全轉變為多主機環境設置,以確保所有節點都有一個就緒的緩衝集區。