高可用架構對於互聯網服務基本是標配,不管是應用服務仍是數據庫服務都須要作到高可用。雖然互聯網服務號稱7*24小時不間斷服務,但多多少少有一些時候服務不可用,好比某些時候網頁打不開,百度不能搜索或者沒法發微博,發微信等。通常而言,衡量高可用作到什麼程度能夠經過一年內服務不可用時間做爲參考,要作到3個9的可用性,一年內只能累計有8個小時不可服務,而若是要作到5個9的可用性,則一年內只能累計5分鐘服務中斷。因此雖然說每一個公司都說本身的服務是7*24不間斷的,但實際上能作到5個9的屈指可數,甚至根本作不到,國內互聯網巨頭BAT(百度,阿里巴巴,騰訊)都有由於故障致使的停服問題。對於一個系統而言,可能包含不少模塊,好比前端應用,緩存,數據庫,搜索,消息隊列等,每一個模塊都須要作到高可用,才能保證整個系統的高可用。對於數據庫服務而言,高可用可能更復雜,對用戶的服務可用,不只僅是能訪問,還須要有正確性保證,所以討論數據庫的高可用方案時,通常會同時考慮方案中數據一致性問題。今天這篇文章主要討論MySQL數據庫的高可用方案,介紹每種方案的特性以及優缺點,本文是對各類方案的總結,但願拋磚引玉,和你們一塊兒討論。html
1.基於共享存儲的方案SAN
方案介紹:SAN(Storage Area Network)簡單點說就是能夠實現網絡中不一樣服務器的數據共享,共享存儲可以爲數據庫服務器和存儲解耦。使用共享存儲時,服務器可以正常掛載文件系統並操做,若是服務器掛了,備用服務器能夠掛載相同的文件系統,執行須要的恢復操做,而後啓動MySQL。共享存儲的架構以下:前端
優勢:
1.能夠避免存儲外的其它組件引發的數據丟失。
2.部署簡單,切換邏輯簡單,對應用透明。
3.保證主備數據的強一致。
限制或缺點:
1.共享存儲是單點,若共享存儲掛了,則會丟失數據。
2.價格比價昂貴。mysql
2.基於磁盤複製的方案 DRBD
方案介紹:DRBD(Distributed Replicated Block Device)是一種磁盤複製技術,能夠得到和SAN相似的效果。DBRD是一個以linux內核模塊方式實現的塊級別同步複製技術。它經過網卡將主服務器的每一個塊複製到另一個服務器塊設備上,並在主設備提交塊以前記錄下來。DRBD與SAN相似,也是有一個熱備機器,開始提供服務時會使用和故障機器相同的數據,只不過DRBD的數據是複製存儲,不是共享存儲。DRBD的架構圖以下:linux
優勢:
1.切換對應用透明
2.保證主備數據的強一致。
限制或缺點:
1.影響寫入性能,因爲每次寫磁盤,實質都須要同步到網絡服務器。
2.通常配置兩節點同步,可擴展性比較差
3.備庫不能提供讀服務,資源浪費web
3.基於主從複製(單點寫)方案
前面討論的兩種方案分別依賴於底層的共享存儲和磁盤複製技術,來解決MYSQL服務器單點和磁盤單點的問題。而實際生產環境中,高可用更多的是依賴MySQL自己的複製,經過複製爲Master製做一個或多個熱副本,在Master故障時,將服務切換到熱副本。下面的幾種方案都是基於主從複製的方案,方案由簡單到複雜,功能也愈來愈強大,實施難度由易到難,各位能夠根據實際狀況選擇合適的方案。
3.1.keepalived/heartbeat
方案介紹:
keepalived是一個HA軟件,它的做用是檢測服務器(web服務器,DB服務器等)狀態,檢查原理是模擬網絡請求檢測,檢測方式包括HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK等,對於DB服務器而言,主要就是IP,端口(TCP_CHECK),但這可能不夠(好比DB服務器ReadOnly),所以keepalived也支持自定義腳本。keepalived基於VRRP協議來實現高可用,每一個服務器所在機器會部署啓動一個keepalived服務,多個keepalived服務中有一個Master,Master定時向其它各個Slave keepalived服務發送心跳包(當不發送心跳包時,則認爲主掛了,須要從新選主),全部的服務器配置指向同一個VIP,正常狀況下,應用訪問VIP時,即訪問的是master配置指向的真實IP;而若是master所在keepalived服務掛了,則基於VRRP協議會從新選一個keepalived Master來提供服務,在這種狀況下,若是master上的DB正常,並且上面有長鏈接,則會形成雙寫。keepalived經過監聽來確認服務器的狀態,若是發現服務器故障,則將故障服務器從系統中剔除(經過關掉自身的keepalived服務實現),keepalived的高可用架構以下圖,分別在主、從服務器上安裝keepalived的軟件,並配置一樣的VIP,VIP層將真實IP屏蔽,應用服務器經過訪問VIP來獲取DB服務。當Master故障時,keepalived感知,並將Slave提高主,繼續提供服務對應用層透明。sql
優勢:
1. 安裝配置簡單
2. Master故障時,Slave快速切換提供服務,而且對應用透明。
限制或缺點:
1.須要主備的IP在同一個網段。
2.提供的檢測機制比較弱,須要自定義腳原本肯定Master是否能提供服務,好比更新心跳錶等。
3.沒法保證數據的一致性,原生的MySQL採用異步複製,若Master故障,Slave數據可能不是最新,致使數據丟失,所以切換時要考慮Slave延遲的因素,肯定切換策略。對於強一致需求的場景,能夠開啓(semi-sync)半同步,來減小數據丟失。
4.keepalived軟件自身的HA沒法保證。數據庫
3.2.MHA
方案介紹:MHA(Master High Availability)是一位日本MySQL大牛用Perl寫的一套MySQL故障切換方案,來保證數據庫的高可用,MHA經過從宕機的主服務器上保存二進制日誌來進行回補,能在最大程度上減小數據丟失。MHA由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。MHA能夠單獨部署在一臺獨立的機器上管理多個master-slave集羣,MHA Node運行在每臺MySQL服務器上,主要做用是切換時處理二進制日誌,確保切換儘可能少丟數據。MHA Manager會定時探測集羣中的master節點,當master出現故障時,它能夠自動將最新數據的slave提高爲新的master,而後將全部其餘的slave從新指向新的master,整個故障轉移過程對應用程序徹底透明。MHA的架構以下:緩存
MHA failover過程:
a.檢測到 Master 異常,進行一系列判斷,最後肯定 Master 宕掉;
b.檢查配置信息,羅列出當前架構中各節點的狀態;
c.根據定義的腳本處理故障的 Master,VIP漂移或者關掉mysqld服務;
d.全部 Slave 比較位點,選出位點最新的 Slave,再與 Master 比較並得到 binlog 的差別,copy 到管理節點;
e.從候選節點中選擇新的 Master,新的 Master 會和位點最新的 Slave 進行比較並得到 relaylog 的差別;
f.管理節點把 binlog 的差別 copy 到新 Master,新 Master 應用 binlog 差別和 relaylog 差別,最後得到位點信息,並接受寫請求(read_only=0);
g.其餘 Slave 與位點最新的 Slave 進行比較,並得到 relaylog 的差別,copy 到對應的 Slave;
h.管理節點把 binlog 的差別 copy 到每一個 Slave,比較 Exec_Master_Log_Pos 和 Read_Master_Log_Pos,得到差別日誌;
i.每一個Slave應用全部差別日誌,而後 reset slave 並從新指向新 Master;
j.新 Master reset slave 來清除 Slave 信息。服務器
優勢:
1. 代碼開源,方便結合業務場景二次開發
2. 故障切換時,能夠修復多個Slave之間的差別日誌,最終使全部Slave保持數據一致,而後從中選擇一個充當新的Master,並將其它Slave指向它。
3. 能夠靈活選擇VIP方案或者全局目錄數據庫方案(更改Master IP映射)來進行切換。
缺點:
1.沒法保證強一致,由於從故障Master上保存二進制日誌並不老是可行,好比Master磁盤壞了,或者SSH認證失敗等。
2.只支持一主多從架構,要求一個複製集羣中必須最少有三臺數據庫服務器,一主二從,即一臺充當master,一臺充當備用master,另一臺充當從庫。
3.採用全局目錄數據庫方案切換時,須要應用感知變化,所以對應用不透明,所以要保持切換對應用透明,依然依賴於VIP。
4.不適用於大規模集羣部署,配置比較複雜。
5.MHA管理節點自己的HA沒法保證。微信
3.3.基於zookeeper的高可用
方案介紹:
從前面的討論能夠看到,不管是keepalived方案仍是MHA方案,都沒法解決HA軟件自身的高可用問題,由於HA自己是單點。那麼若是將HA也引入多個副本呢?那麼又帶來新的問題,1.HA軟件之間如何保證強同步。2.如何確保不會有多個HA同時進行切換動做。這兩個問題實質都分佈式系統一致性問題,爲此,能夠爲HA軟件引入相似Paxos,Raft這樣的分佈式一致性協議,保證HA軟件的可用性。zooKeeper是一個典型的發佈/訂閱模式的分佈式數據管理與協調框架,經過zookeeper中豐富的數據節點類型進行交叉使用,配合watcher事件通知機制,能夠方便地構建一系列分佈式應用涉及的核心功能,好比:數據發佈/訂閱,負載均衡,分佈式協調/通知,集羣管理,Master選舉,分佈式鎖和分佈式隊列等。zookeeper是一個很大話題,你們能夠google去找更多的信息,我這裏主要討論zookeeper如何解決HA自身可用性問題。架構圖以下:
圖中每一個MySQL節點上面部署了一個HA client,用於實時向zookeeper彙報本地節點的心跳狀態,好比主庫crash,經過修改zookeeper(如下簡稱zk)上的節點信息,來通知HA。HA節點在zk上註冊監聽事件,當zk節點發生變化時會自動讓HA感知,HA節點能夠部署一個或多個,主要用於容災。HA節點之間經過zookeeper服務來實現數據的一致性,經過分佈式鎖保證多個HA節點不會同時對一個主從節點進行切換。HA自己是無狀態的,全部MySQL節點狀態信息所有保存在zookeeper服務器上,切換時,HA會對MySQL節點進行復檢,而後切換。咱們看看引入zookeeper後的切換流程:
a.HA client 檢測到 Master 異常,進行一系列判斷,最後肯定 Master 宕掉;
b.HA client 刪除 Master在zk上的節點信息;
c.因爲監聽機制,HA會感知到有節點被刪除;
d.HA對MySQL節點進行復檢,好比創建鏈接,更新心跳錶等
e.確認異常後,則進行切換。
咱們再看看這種架構下,是否能保證HA自身的高可用
(1).若是HA-client自己掛了,MySQL節點正常?
HA-Client管理的MySQL節點沒法與zookeeper保持心跳,zk服務將節點刪除,HA會感知到這種變化,準備嘗試一次切換,切換前,會進行復檢,複檢時發現MySQL節點是OK的,則不會切換。
(2).MySQL節點與zookeeper的網絡斷了,那麼表現如何?
因爲HA-Client與節點在同一臺主機,所以HA-client沒法再定時向zk彙報心跳,zk會將對應的MySQL節點信息刪除,HA嘗試複檢,依然失敗,則進行切換。
(3).HA掛了,表現如何?
因爲HA無狀態,而且有多個副本,所以一個HA掛了,不會對整個系統形成影響。
優勢:
1. 保證了整個系統的高可用
2. 主從的強一致依賴於MySQL自己,好比半同步,或者外圍工具的回補策略,相似MHA。
3. 擴展性很是好,能夠管理大規模集羣。
缺點:
1.引入zk,整個系統變得複雜。
4.基於Cluster(多點寫)方案
第3節討論的方案基本是目前業內使用的主流方案,這類方案的特色是,單點寫。雖然咱們能夠藉助中間件進行分片(sharding),可是對於同一份數據,依然只容許一個節點寫,從這個角度來講,上面的方案是僞分佈式。下面討論的兩種方案算是真正分佈式,同一個數據理論上能夠在多個節點寫入,相似於Oracle的RAC,EMC的GreenPlum這種分佈式數據庫。在MySQL領域,主要提供了2種解決方案:基於Galera的PXC和NDB Cluster。MySQL Cluster實現基於NDB存儲引擎,使用不少侷限性,而PXC是基於innodb引擎,雖然也有侷限性,但因爲目前innodb使用很是普遍,因此有必定的參考價值。目前據我所知,去哪兒公司在他們的生產環境中使用了PXC方案。PXC(Percona XtraDB Cluster)的架構圖以下:
優勢:
1.準同步複製
2.多個可同時讀寫節點,可實現寫擴展,較分片方案更進一步
3.自動節點管理
4.數據嚴格一致
5.服務高可用
缺點:
1.只支持innodb引擎
2.全部表都要有主鍵
3.因爲寫要同步到其它節點,存在寫擴大問題
4.很是依賴於網絡穩定性,不適用於遠距離同步
5.基於中間件proxy的方案
準確地來講,中間件與高可用沒有特別大的關係,由於切換都是在數據庫層完成,但引入中間層後,使得對應用更透明。在引入中間件以前,全部的方案,基本都依賴於VIP漂移機制,或者不依賴於VIP又不能保證對應用透明。經過加入中間件層,能夠同時實現對應用透明和高可用。此外中間層還能夠作sharding,方便寫擴展。proxy的方案不少,好比mysql自帶的mysql-proxy和fabric,阿里巴巴的cobar和tddl等。咱們以fabric爲例,其架構圖以下:
應用都請求 Fabric 鏈接器,而後經過使用 XML-RPC 協議訪問 Fabric 節點, Fabric 節點依賴於備用存儲 (backing store),裏面存儲整個 HA 集羣的元數據信息。鏈接器讀取 backing store 的信息,而後將元數據緩存到 cache,這樣作的好處就是減小每次創建鏈接時與管理節點交互所帶來的開銷。Fabric 節點可管理多個 HA Group,每一個 HA Group 裏有一個 Primary 和多個 Secondary(slave),當 Primary 異常的時候會從 Secondary 中選出最合適的節點提高爲新 Primary,其他 Secondary 都將從新指向新 Primary。這些都是自動操做,對業務是無感知的,HA 切換以後還須要通知鏈接器更新的元數據信息。
優勢:
1.切換對應用透明
2.可擴展性強,方便分片擴展
3.能夠跨機房部署切換
缺點:
1.是一個比較新的組件,沒有不少實際應用場景
2.沒有解決強一致問題,主備強一致性依賴於MySQL自身(半同步),以及回滾回補機制。
總結
以上介紹了目前MySQL幾種典型的高可用架構,包括基於共享存儲方案,基於磁盤複製方案和基於主從複製的方案。對於主從複製方案,分別介紹了keepalived,MHA以及引入zookeeper的方案。對於每種方案,都從持續可用,數據強一致性,以及切換對應用的透明性進行說明。我的以爲基於MySQL複製的方案是主流,也很是成熟,引入中間件和引入zookeeper雖然能將系統的可用性作地更好,可支撐的規模更大,但也對研發和運維也提出了更高的要求。所以,在選擇方案時,要根據業務場景和運維規模作抉擇。
參考文檔
http://hedengcheng.com/?p=892
http://imysql.cn/tag/pxc
http://www.cnblogs.com/gomysql/p/3675429.html
http://www.2cto.com/database/201407/319748.html
http://chuansong.me/n/2250351
http://blog.csdn.net/lichangzhen2008/article/details/44708227