mysql 高可用方案漫谈(二)
生活随笔
收集整理的這篇文章主要介紹了
mysql 高可用方案漫谈(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
引言:
上一期介紹了對于單個實例主備切換的涉及的業務細節,這次我們更深一步,討論下真實場景中主庫故障,或者網絡出現故障時涉及到的問題。如果有不妥的地方,歡迎大家指正。主庫故障:
故障分類
一般的,我們會發現mysql 不可用的原因有幾下幾類: 1,主機硬件損壞,導致主機hang死,或者操作系統crash。此時客戶端連接主機上的mysql進程時的表現是連接超時。因為不會回復ack包。此種情況與網絡中斷不能回包的表現是一樣的,所以對于外部是無法判定是主機down還是網絡故障的。我們遇到過raid 卡損壞,磁盤故障,電源模塊損壞,起火等等。 2,操作系統配置或者環境問題,比如ipfilter 某個參數配置過小或者BUG,設置出錯等,導致drop 掉某些包,會導致實例部分連接沒有響應,但是主機可能還可以登錄。此時與1的外部表現也是相同的。 3,mysql 自身BUG,或者某些異常 sql 導致mysql 自身crash,此種情況是mysql 進程crash,主機是完好的,所以可以通過連接主機其他端口驗證出是進程故障還是主機故障。 4,mysql 實例性能問題,比如用戶執行一個大事務,刷pageCache或者寫log,導致磁盤IOUTIL 打滿,此時表現是連接超時,或者連接可以建立,但是執行update語句超時。此時主庫log 一般是可以正常傳送到被庫的。 針對以上故障,我們可能需要進行故障切換,故障切換最重要的兩條原則,1)保證數據安全,保證數據可靠性。2)在一定時間內能快速響應,提高可用性。可靠性保障:
可靠性概述
可靠性保障最重要的就是要確保被庫與主庫數據保持一致,進一步就是說主庫寫入的binlog都要能夠傳遞到備庫。在異步模式下,是無法保證的,在半同步模式下,大部分情況可以保證,為什么說是大部分情況,因為有可能是備庫剛剛down機,啟動后,正在IO線程追主庫log,此時復制還是異步模式,但追上后,才會自動轉為半同步模式。如果此時主庫再down機,那么也一定會有部分log還在主庫上。如果說要保證一定傳到備庫,保證數據強一致,那么當備庫down機時,主庫就不應該繼續提供服務,此種用法在其他主流數據庫中也可以設置,但是很少使用,因為對可用性影響較大,因為如果一旦備庫down機,或者主備間網絡斷開,那么主庫可用性立即就受到影響,這種對于一般用戶來說是不可接受的。進一步,有人引入了一主多備模式,當有一個備庫返回已經收到最后一條日志后,就可以給用戶返回commit成功,這樣提高了主庫的可用性,同時也提高了成本。 言歸正傳,在一主一備的阿里云主流模式下,我們對于需要較高可靠性的用戶,推薦使用半同步模式。集團內部的MHA系統提供了當主庫故障時,從原主庫同步log到備庫,追上一段后,再提供服務的方案,此種方案能work的前提是原主庫依然可以連接并且讀取磁盤,并且會犧牲一段可用性時間,好處是可以補充一段binlog,讓備庫數據與主庫一致。其實是可以作為一個比較好的補充手段。 RDS這里對用戶實例做了24小時不間斷的被庫延遲監控,所以對于數據延遲的實例會提前報警,避免當主機完全不可恢復時,數據丟失。 ##如何應對 考慮這樣的場景,主備庫分別部署在A,B兩個機房做容災,HA的兩個節點也分別部署在兩個機房,當A,B機房間發生網絡故障,但是A,B機房自身正常時,兩邊的HA 都分別看見對端的實例節點放生故障,會將自己機房的實例提升為主庫,那么此時如果兩個機房都有流量進來,那么就可能導致數據庫“雙寫”,也就是會發生著名的“腦裂”問題。 如果要解決“腦裂”問題,兩個節點是不夠的。那么我們引入了第三個節點,部署在另外一個機房,該節點無數據,只負責“腦裂”判定。這樣構成了一個三個節點的三角模式(mongoDB,mssql 都是類似做法),三個點可以分別部署zookeeper 客戶端并且選主,同一時刻,3個節點間只能有一個為leader。3個節點中任意兩個節點活著,那么實例可用。如果3個節點中兩個或者3個節點掛掉,實例不可用。當A機房掛掉,或者實例在A機房的主機掛掉,那么leader 在B,C機房產生,此時由于B 機房可以連通leader 那么認為自己可以繼續服務;C 機房掛掉,那么leader 在A,B中產生,A,B 都能連通leader ,那么仍然都可以繼續服務。
網絡故障場景
考慮網絡故障情況, A為主,B為備,C為裁判: 1)當A機房與B機房網絡不通,3個節點都正常,A到C,B到C都正常。 leader 在A,那么A,C為多數派,A繼續提供服務。 leader 在B,那么A摘除自己,B,C之間重新選擇leader ,將B提升為新主庫。 leader 在C,那么A, B服務不受影響,但是備庫復制線程中斷。 2)當A機房與C機房網絡不通, leader 在A,那么C 不能獲取狀態,摘除,B能與A leader 連接,繼續work,A由于與B連通,投票多數,那么繼續work ,不受影響。 leader 在B,那么A,C節點都與leader B可以通信,那么整體都可以work, 無任何影響。 leader 在C,那么A與C不通,那么A自己down掉自己,B與leader C通,所以B可以work , 將B中實例節點提升為主庫。 3)當A與B,C機房都不通, leader在A,B,C重新選leader ,那么A自己不work,然后B提升為主庫。 leader在B或者C, 不必選leader , A自己不work,然后B提升為主庫。 4)當B與C不通,與A通,B為備庫,自己摘除自己,不影響可用。 leader在A,B與leader A通,那么不受影響。 leader在B,A和B構成多數派,繼續提供服務。 leader在C,那么由于A與C通,B摘除自己,主庫A繼續提供服務。 5)當B與A,C都不通,A,C之間通,那么在A,C間重新選leader , 然后A繼續提供服務。 6)當C與A,B 都不通,那么A,B將重新選擇leader ,A繼續提供服務。 當B 為主庫時,分析與上面類似,綜上,可以認為當主庫本身節點與leader 節點不通,或者自己是leader節點,但是與另外兩個節點都不通,自己成為少數派時,會發生failover,其余情況都可以正常工作。解決了“腦裂“問題,關鍵點就在于當節點自身發現是少數派時,自我管理,自己將自己殺掉。 同時,HA 按照正常邏輯提升備庫為新主庫,保證可用性。 #結合現實 回到現實中,因為條件有限,有些時候沒辦法都部署三機房,所以在兩機房時,如果是C節點與B部署在一邊,A節點此時是主庫,那么當C所在的機房整體down機,那么數據庫主節點A由于與leader節點不通,將自己關閉自己的寫入,并且此時由于B與C所在節點down機,B也無法提供服務,那么此時實例就無法提供服務。 如果A節點主庫與 B.C所在的機房網絡不通,但是B,C機房可以提供服務,那么主庫會自動failover到B節點,此時B和C選出一個leader , 繼續提供服務,沒有問題。總結
本期主要從實際角度出發,闡述了一些場景,下一期會從2pc,3pc,分區一致性等理論角度來探討下如何保證節點間的數據一致性。以及mysql 主庫故障并且log 未傳遞到備庫時,恢復備庫可能的手段。總結
以上是生活随笔為你收集整理的mysql 高可用方案漫谈(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程与网络之NSURLConnecti
- 下一篇: Ibatis学习总结1--ibatis简