MySQL是數據庫領域當之無愧的霸主之一,其在各行各業被廣泛應用,隨著廣泛使用,對于MySQL本身的高可用性的要求就是不可避免的話題,而MySQL的高可用方案也隨著MySQL功能的完善經歷了多次升級,本文將對MySQL的各種高可用架構進行分析,以此來了解架構的演進。
冗余是高可用設計的核心
高可用的核心是避免單點故障(SPOF),而避免單點故障的最經典的解決方案是增加冗余。
不同的高可用方案在冗余方式和冗余的程度上有所差別。
冗余方式上面,有些是在底層存儲上進行冗余,有些是對整個主機進行冗余,有些是跨IDC的冗余。
冗余程度上面,有些是災備級別允許一定程度的數據丟失,有些也是要求數據的強一致性。
MySQL的各種高可用方案的核心就是圍繞著冗余的設計展開。
MySQL復制技術發展史
MySQL的高可用方案基于MySQL的復制技術,復制技術的核心就是增加一個MySQL節點的冗余。
1. MySQL Replication引入
2000年,MySQL 3.23.15版本引入了MySQL Replication技術,一經推出就得到了較為廣泛的使用。Replication是一種異步的數據復制機制,實現的是近實時的數據同步效果。此時的Replicaton主要通過兩個線程實現,一個在Master節點,一個在Slave節點。Slave首先通過Master獲取到數據變動的event,然后將這個event在Slave節點進行replay重放。
這種方式存在一個比較明顯的缺點,那就是replay會涉及到數據的寫入,屬于IO操作,速度比較慢,因為讀取event和replay是在同個流程中,replay速度慢會導致讀取event的缺速度也比較慢,當主節點寫入的速度較快的時候,就會導致大量主備延遲,binary log會積壓大量沒有備份到Slave的情況,一旦Master節點出問題,Slave節點啟用的話會出現大量數據落后的不一致情況,且Slave節點也無法作為讀節點對外提供服務。
2. Relay Log引入
2002年,MySQL4.0.2引入了relay log,將Slave端讀取event和數據replay分開成了兩個流程,分別由IO線程和SQL線程兩個線程負責。其中,IO線程負責從Master節點讀取event,然后寫入本地的relay log,SQL線程從relay log中讀取event然后執行,將數據寫入本地庫。這樣子一來,即使SQL線程執行緩慢,也只是relay log擠壓,Master的binary log會通過IO線程盡可能快地同步到Slave節點,一旦Master出問題,切換到Slave,不會出現大量數據丟失不一致的情況,雖然還是有可能部分數據未及時通過IO線程寫入relay log,但是程度大大地減輕了。
3.半同步復制引入
2010年,為解決異步復制Slave節點可能在Master宕機的情況下丟失binary log的問題,引入了半同步復制。在半同步復制的機制下,Master節點在應答客戶端提交的事務之前需要保證至少一個Slave接收到Master的event并寫realy log成功。
當然半同步還是存在一些問題:
1、解決了Master宕機情況下relay log丟失的問題,但是仍然非強一致性,relay log可能還未被SQL線程寫入本地庫,此時的查詢仍然會有數據落后的可能。
2、主節點宕機,binary log還未傳給半同步節點,但是已經寫入本地binary log,此時切換到半同步節點運行,等待原主節點恢復以后,已經寫入的binary log會被繼續傳給半同步節點,可能造成主鍵沖突。
3、無法很好的支持故障自動切換的場景。
4.組復制的引入
2016年,MySQL5.7.17版本引入了Group Replication技術,這是一個“邏輯上”的同步的機制,在第一個節點收到一個事務時,會將事務廣播到集群中的其他節點,等收到過半數節點同意以后,事務會在各個節點上獨立提交,也就是說各個節點只是在決定事務是否沖突、能否提交的階段是同步的,而事務的提交是異步的。Group Replication技術是一項支持高可用、強數據一致性的方案,并且最重要的是將不再僅僅只是著眼于提供一個冗余備份,而是從一個集群的角度上來保障高可用和數據一致性,支持流控、故障自動切換等特性,運維比較簡單,在高可用和性能上實現了較好的平衡,整體優缺點總結如下:
優點:
1、強一致性:基于分布式paxos變種協議實現組復制,保證數據強一致性;
2、高容錯性:自動故障和節點異常檢測機制,集群過半數節點正常運行就可以保證集群的可用性。
3、跨機房部署:過半數的節點的機制,適合跨機房的集群容錯部署,同個機房內的節點網絡間通訊的延遲較小。
4、高擴展性:節點的增加與移除會自動更新組成員信息,新節點加入后,自動從其他節點同步增量數據,直到與其他節點數據一致,過程簡單,無需過多的人工干預。
5、多種模式:支持單主與多主模式
缺點:
1、集群要求比較穩定的網絡環境,不適用于WAN場景。
2、多主情況下容易有沖突發生,造成業務交易成功率低。
3、資源消耗較多
其他的高可用方案
- 基于異步復制的主從方案
最常見的高可用方案之一是采用異步復制的方式,增加一個或者多個從節點,以實現主節點異常時可以快速切換,這種情況下經常會有binary log落后的情況,一般情況下也無法很好的實現自動切換,所以很多時候作為災備使用,并且業務上能夠接受一些數據丟失的情況。 - 使用SAN共享存儲
傳統的數據庫產品會使用SAN共享存儲在存儲數據,多個數據庫實例并發訪問共享存儲存取數據,應用通過虛擬IP訪問數據庫,當某個數據庫掛掉以后會由其他正常的實例接管虛擬IP繼續對外提供服務。這種方案有明顯的問題,一在于共享存儲的成本高,二在于共享存儲本身又稱為了單點。 - 使用DRBD網絡RAID方案
DRBD是一個用軟件實現的、無共享的、服務器之間鏡像塊設備內容的存儲復制解決方案,實際使用并不多,主要原因在于DRBD本身速度會成為瓶頸,并且通過基于塊的存儲復制,只能作為災備,無法同時對外提供服務,存在比較大的資源浪費。 - 使用NFS等網絡文件系統
這種方案類似使用SAN共享存儲,但是性能會更差,網絡文件系統難以實現高吞吐,瓶頸非常明顯。 - 使用分布式文件系統
使用分布式文件系統存放數據是另外一種考慮的方向,不同的數據庫實例可以使用分布式文件系統的數據,一致性和高可用交由底層分布式文件系統處理,但是這種模式下也很難實現故障的切換,并且引入分布式文件系統更加復雜。 - 使用主主架構
主主架構其實本質上也是異步復制,相對于主從,主主架構的好處在于當其中一個節點故障時可以直接切換,免去了從節點切換為主節點的流程。但是,一般建議不要使用,因為可能存在主鍵沖突、從節點上誤操作同步到了主節點等情況,使用主從架構更加穩健。這種架構適用于對數據沒有強一致性要求,允許丟失少量數據的情況,當做災備或者提供更大的讀能力的場景。 - MariaDB Galera Cluster
MariaDB是Mysql的一個分支,在業內也是被廣泛使用的,Galera Cluster是MariaDB提供的高可用的集群方案,其在MySQL InnoDB存儲引擎基礎上打了wrep(虛擬全同步復制)patch,提供了強一致性、高可用的能力,Percona/MariaDB各自的發行版都支持了這個功能,目前支持XtraDB/InnoDB存儲引擎。Galera Cluster有以下優缺點:優點:
1、同步復制(注意,這里的同步仍然是指事務發送到各個節點的過程,事務在各個節點的應用的過程仍然是異步的,各個節點獨立的)2、真正的 multi-master,所有節點可以同時讀寫數據庫3、自動的節點成員控制,失效節點自動被清除4、新節點加入數據自動復制、支持并行復制5、事務不丟失,不存在主從不一致的情況下缺點:
1、一般只支持三個節點,網絡越慢,主節點越多,則越容易有性能的瓶頸,集群擴展性受限。2、事務的提交需要等待集群所有節點的確認回復,無法支持跨機房部署的場景,因為跨機房的網絡抖動延遲較大。3、多主情況下容易有沖突發生,造成業務交易成功率低。4、非MySQL官方,雖然社區也很優秀,但對于一些企業來說,會要求官方版本。
- MySQL NDB Cluster
MySQL NDB Cluster是MySQL官方提供的集群同步方案,是一個真正全同步的方案,整體架構如下:
集群分為三種角色:
Management Node
實現對集群其他節點的管理,維護元數據信息,例如數據節點內存大小、數據節點數據存放位置,SQL節點位置信息等。
SQL Node
數據節點不直接提供應用程序訪問,SQL節點對接應用程序,轉發請求到數據節點,Cluster中可以有多個SQL節點,每個SQL節點查詢到的數據都是一致的,一般來說,SQL節點越多,分配到每個SQL節點的負載就越小,系統的整體性能就越好。
Data Node
存取數據,提供真正的數據查詢操作。
依賴集群自身提供的同步機制,每個數據節點中的數據都是強一致的,事務的執行是同步的。
NDB Cluster的優缺點都比較明顯:
優點:
1、數據能夠實現自動分片,具備較強的寫入擴展能力。
2、分布式、無共享架構,強一致性,具備較強的故障恢復能力。
3、基于內存,實時性較高,性能較好。
缺點:
1、數據存放在內存,擴展能力受到內存大小的限制。
2、隨著節點數量的增加,網絡通訊的代價會越來越高,性能會容易產生瓶頸。
3、引入了Management Node和SQL Node,集群管理成本顯著增加。
故障切換的方式
隨著不同的高可用架構的出現,伴隨而來的是多種不同的故障切換的方式,不同的高可用架構需要配套合適的切換方式才能真正發揮故障容災的作用。
1、應用修改配置切換
當某個數據庫節點出現故障以后,手工修改配置指向備庫節點,需要重啟服務,人工介入,效果極差。
2、DNS動態解析
使用域名訪問數據庫,采用DNS解析的方式將具體連接的IP信息返回給應用程序,編寫特定的檢查腳本檢測主節點的可用性,當出現故障時動態修改DNS解析到備節點。這種方式的困難點在于DNS會有有效期內的緩存,雖然可以調整緩存時間,但操作起來還是不夠方便。
3、MMM
MMM(Master-Master replication manager for MySQL),是一套支持雙主故障切換和雙主日常管理的腳本程序,其原理是通過漂移虛擬IP的方式來處理單點故障,主要應用于MySQL雙主模式,注意,雙主只是意味著兩個節點都可以當作主節點使用,但是同一時刻只能有一個主節點對外提供服務。
其架構圖如下所示,每個節點上都安裝了mmm_agent,用于與mmm monitor通訊。
mmm_monitor:監控進程,負責所有的監控工作,決定和處理所有節點角色活動。
mmm_agent:運行在每個mysql服務器上的代理進程,完成監控的探針工作和執行簡單的遠端服務設置命令。
mmm_monitor端會決定哪些VIP應該掛載哪個mysql節點上,當某一個節點出現異常,其能夠將VIP切到其他的節點。
值得注意的是,MMM模式使用起來并不方便,生產應用證明也不是很可靠,故應用不廣泛,項目已經很久沒有更新了。
4、MHA
MHA(Master High Availability)是目前相對成熟的一套方案,用于進行故障切換和主從提升,能夠在0~30秒之內自動完成數據庫的故障切換操作,并且在進行故障切換的過程中,MHA能在最大程度上保證數據的一致性。
MHA支持修改全局配置以及漂移虛擬IP,能夠實現故障切換對應用無感知,應用比較廣泛,被普遍生產應用證明了可靠性。
MHA架構引入了MHA Manage,可以獨立部署在一臺服務器上MHA Manager會定時探測集群中的master節點,當master出現故障時,它可以自動將最新數據的slave提升為新的master,然后將所有其他的slave重新指向新的master。整個故障轉移過程對應用程序完全透明,MHA模式適用于一主多從的場景。
5、自定義Proxy
采用Haproxy等負載均衡設備,在Haproxy上配置虛擬IP,應用程序訪問虛擬IP,haproxy負責進行連接管理和請求的轉發,另外可以編寫故障檢查腳本,當發現故障節點,haproxy自動將相關請求轉發到其他節點,實現自動恢復,這是一種比較靈活的方案。
總結一下,本文從復制技術開始,逐一分析了Mysql從最基本的異步復制到組復制,業內常用的多種高可用方案和故障切換方式,也對相關方案的優缺點進行了討論。實際應用中,需要根據具體業務場景進行方案的選擇,綜合對于數據一致性的要求、運維復雜程度、跨機房的要求等方面的考慮,選擇合適的方案。