閱讀125 返回首頁    go 技術社區[雲棲]


美團點評數據庫高可用架構的演進與設想

在2015年之前,美團點評(點評側)長期使用MMM(Master-Master replication manager for MySQL)做數據庫高可用,積累了比較多的經驗,也踩了不少坑,可以說MMM在公司數據庫高速發展過程中起到了很大的作用。

MMM的架構如下:

06184c862f1b91ceb99017cfd1a2f7ac6e596c7d

如上所示,整個MySQL集群提供1個寫VIP    (Virtual IP)和N(N>=1)個讀VIP提供對外服務。每個MySQL節點均部署有一個Agent(mmm-agent),mmm-agent和mmm-manager保持通信狀態,定期向mmm-manager上報當前MySQL節點的存活情況(這裏稱之為心跳)。當mmm-manager連續多次無法收到mmm-agent的心跳消息時,會進行切換操作。

mmm-manager分兩種情況處理出現的異常:

1.出現異常的是從節點
  • mmm-manager會嚐試摘掉該從節點的讀VIP,並將該讀VIP漂移到其它存活的節點上,通過這種方式實現從庫的高可用。
2.出現異常的是主節點
  • 如果當時節點還沒完全掛,隻是響應超時。則嚐試將Dead Master加上全局鎖(flush tables with read lock)。
  • 在從節點中選擇一個候選主節點作為新的主節點,進行數據補齊。
  • 數據補齊之後,摘掉Dead Master的寫VIP,並嚐試加到新的主節點上。
  • 將其它存活的節點進行數據補齊,並重新掛載在新的主節點上。

主庫發生故障後,整個集群狀態變化如下:

05c0026367fe822aec648aaeeb7fc6118f2c4d6a

mmm-manager檢測到master1發生了故障,對數據進行補齊之後,將寫VIP漂移到了master2上,應用寫操作在新的節點上繼續進行。

然而,MMM架構存在如下問題:

  • VIP的數量過多,管理困難(曾經有一個集群是1主6從,共計7個VIP)。某些情況下會導致集群大部分VIP同時丟失,很難分清節點上之前使用的是哪個VIP。
  • mmm-agent過度敏感,容易導致VIP丟失。同時mmm-agent自身由於沒有高可用,一旦掛掉,會造成mmm-manager誤判,誤認為MySQL節點異常。
  • mmm-manager存在單點,一旦由於某些原因掛掉,整個集群就失去了高可用。
  • VIP需要使用ARP協議,跨網段、跨機房的高可用基本無法實現,保障能力有限。

同時,MMM是Google技術團隊開發的一款比較老的高可用產品,在業內使用的並不多,社區也不活躍,Google很早就不再維護MMM的代碼分支。我們在使用過程中發現大量Bug,部分Bug我們做了修改,並提交到開源社區,有興趣的同學可以參考這裏。

MHA

針對於此,從2015年開始,美團點評對MySQL高可用架構進行了改進,全部更新為MHA,很大程度上解決了之前MMM遇到的各種問題。

MHA(MySQL Master High Availability)是由Facebook工程師Yoshinori Matsunobu開發的一款MySQL高可用軟件。從名字就可以看出,MHA隻負責MySQL主庫的高可用。主庫發生故障時,MHA會選擇一個數據最接近原主庫的候選主節點(這裏隻有一個從節點,所以該從節點即為候選主節點)作為新的主節點,並補齊和之前Dead Master 差異的Binlog。數據補齊之後,即將寫VIP漂移到新主庫上。

整個MHA的架構如下(為簡單起見,隻描述一主一從):

b1a13bced5d4636c057a1a72de4e9f04ee07e65f

這裏我們對MHA做了一些優化,避免一些腦裂問題。

比如DB服務器的上聯交換機出現了抖動,導致主庫無法訪問,被管理節點判定為故障,觸發MHA切換,VIP被漂到了新主庫上。隨後交換機恢複,主庫可被訪問,但由於VIP並沒有從主庫上摘除,因此2台機器同時擁有VIP,會產生腦裂。我們對MHA Manager加入了相同機架上其他物理機的探測,通過對比更多的信息來判斷是網絡故障還是單機故障。


Zebra(斑馬)是美團點評基礎架構團隊開發的一個Java數據庫訪問中間件,是在c3p0基礎上包裝的美團點評內部使用的動態數據源,包括讀寫分離、分庫分表、SQL流控等非常強的功能。它和MHA配合,成為了MySQL數據庫高可用的重要一環。如下是MHA+Zebra配合的整體架構:

9df4015b001ed968799fbcd12e8265edb194bf3d

還是以主庫發生故障為例,處理邏輯有如下兩種方式:

  • 當MHA切換完成之後,主動發送消息給Zebra monitor,Zebra monitor更新ZooKeeper的配置,將主庫上配置的讀流量標記為下線狀態。
  • Zebra monitor每隔一段時間(10s ~ 40s)檢測集群中節點的健康狀況,一旦發現某個節點出現了問題,及時刷新ZooKeeper中的配置,將該節點標記為下線。

一旦節點變更完成,客戶端監聽到節點發生了變更,會立即使用新的配置重建連接,而老的連接會逐步關閉。整個集群故障切換的過程如下(僅描述Zebra monitor主動探測的情況,第一種MHA通知請自行腦補^_^)。

e460cd0310bb7d18b32ea8a47bbfde9f7f689be3

由於該切換過程還是借助於VIP漂移,導致隻能在同網段或者說同個二層交換機下進行,無法做到跨網段或者跨機房的高可用。為解決這個問題,我們對MHA進行了二次開發,將MHA添加VIP的操作去掉,切換完之後通知Zebra monitor去重新調整節點的讀寫信息(將Write調整為new master的實IP,將Dead Master的讀流量摘除),整個切換就完全去VIP化,做到跨網段、甚至跨機房切換,徹底解決之前高可用僅局限於同網段的問題。上述切換過程就變成了如下圖:

1adb8cae1380a23763f96ea340b1995be560c5c4

然而,這種方式中的MHA管理節點是單點,在網絡故障或者機器宕機情況下依然存在風險。同時,由於Master-Slave之間是基於Binlog的異步複製,也就導致了主庫機器宕機或者主庫無法訪問時,MHA切換過程中可能導致數據丟失。

另外,當Master-Slave延遲太大時,也會給數據補齊這一操作帶來額外的時間開銷。


除了Zebra中間件,美團點評還有一套基於Proxy的中間件,和MHA一起配合使用。當MHA切換後,主動通知Proxy來進行讀寫流量調整,Proxy相比Zebra更加靈活,同時也能覆蓋非Java應用場景。缺點就是訪問鏈路多了一層,對應的Response Time和故障率也有一定增加。有興趣的同學們可以自行前往GitHub查詢詳細文檔。


上文提到的MHA架構依然存在如下兩個問題:

  • 管理節點單點。
  • MySQL異步複製中的數據丟失。

針對於此,我們在部分核心業務上使用Semi-Sync,可以保證95%以上場景下數據不丟失(依然存在一些極端情況下無法保障數據的強一致性)。另外,高可用使用分布式的Agent,在某個節點發生故障後,通過一定的選舉協議來選擇新的Master,從而解決了MHA Manager的單點問題。

針對上述問題,我們研究了業界的一些領先的做法,簡單描述如下。

主從同步數據丟失

針對主從同步的數據丟失,一種做法是創建一個Binlog Server,該Server模擬Slave接受Binlog日誌,主庫每次的數據寫入都需要接收到Binlog Server的ACK應答,才認為寫入成功。Binlog Server可以部署在就近的物理節點上,從而保證每次數據寫入都能快速落地到Binlog Server。在發生故障時,隻需要從Binlog Server拉取數據即可保證數據不丟失。

分布式Agent高可用

針對MHA管理節點單點問題,一種做法是讓MySQL數據庫集群中每個節點部署Agent,發生故障時每個Agent均參與選舉投票,選舉出合適的Slave作為新的主庫,防止隻通過Manager來切換,去除MHA單點。整個架構如下圖所示。

cbc81a690f26aac380cd2ebf6783d2a62ae2d825

MGB結合中間件高可用

上述方式某種程度上解決了之前的問題,但是Agent和Binlog Server卻是新引入的風險,同時Binlog Server的存在,也帶來了響應時間上的額外開銷。有沒有一種方式,能夠去除Binlog Server和Agent,又能保證數據不丟失呢 ?答案當然是有的。

最近幾年,MySQL社區關於分布式協議Raft和Paxos非常火,社區也推出了基於Paxos的MGR版本的MySQL,通過Paxos將一致性和切換過程下推到數據庫內部,向上層屏蔽了切換細節。架構如下(以MGR的single-primary為例)。

514749db56f078f9832fa0cffa4f9367bdfd2610

當數據庫發生故障時,MySQL內部自己進行切換。切換完成後將topo結構推送給Zebra monitor,Zebra monitor進行相應的讀寫流量變更。不過,該架構存在與Binlog Server同樣的需要回複確認問題,就是每次主庫數據寫入,都需要大多數節點回複ACK,該次寫入才算成功,存在一定的響應時間開銷。同時,每個MGR集群必須需要奇數個數(大於1)的節點,導致原先隻需要一主一從兩台機器,現在需要至少三台,帶來一定的資源浪費。但不管怎麼說,MGR的出現是無疑是MySQL數據庫又一次偉大的創新。


本文介紹了美團點評MySQL數據庫高可用架構從MMM到MHA+Zebra以及MHA+Proxy的演進曆程,同時也介紹了業界一些高可用的做法。數據庫最近幾年發展突飛勐進,數據庫的高可用設計上沒有完美的方案,隻有不斷的突破和創新,我們也一直在這條路上探索更加優秀的設計與更加完美的方案。


原文發布時間為:2017-11-20

本文作者:金龍

本文來自雲棲社區合作夥伴“數據和雲”,了解相關信息可以關注“數據和雲”微信公眾號

最後更新:2017-11-22 02:33:44

  上一篇:go  雙11享Go了嗎?2017阿裏雙11在線峰會續寫科技盛宴!
  下一篇:go  Android怎麼找到最優適配資源