踩坑無數(shù),美團(tuán)點(diǎn)評高可用數(shù)據(jù)庫架構(gòu)演進(jìn)
同時,也和業(yè)界其他方案進(jìn)行綜合對比,了解業(yè)界在高可用方面的進(jìn)展和未來我們的一些規(guī)劃和展望。
MMM
在 2015 年之前,美團(tuán)點(diǎn)評(點(diǎn)評側(cè))長期使用 MMM(Master-Master replication manager for MySQL)做數(shù)據(jù)庫高可用。
因此我們積累了比較多的經(jīng)驗(yàn),但也踩了不少坑,可以說 MMM 在公司數(shù)據(jù)庫高速發(fā)展過程中起到了很大的作用。
MMM 的架構(gòu)如下:
如上圖所示,整個 MySQL 集群提供 1 個寫 VIP(Virtual IP)和 N(N>=1)個讀 VIP 的對外服務(wù)。
每個 MySQL 節(jié)點(diǎn)均部署有一個 Agent(mmm-agent),mmm-agent 和 mmm-manager 保持通信狀態(tài),定期向 mmm-manager 上報當(dāng)前 MySQL 節(jié)點(diǎn)的存活情況(這里稱之為心跳)。
當(dāng) mmm-manager 連續(xù)多次無法收到 mmm-agent 的心跳消息時,會進(jìn)行切換操作。
mmm-manager 分兩種情況處理出現(xiàn)的異常:
- 出現(xiàn)異常的是從節(jié)點(diǎn),mmm-manager 會嘗試摘掉該從節(jié)點(diǎn)的讀 VIP,并將該讀 VIP 漂移到其他存活的節(jié)點(diǎn)上,通過這種方式實(shí)現(xiàn)從庫的高可用。
- 出現(xiàn)異常的是主節(jié)點(diǎn),如果當(dāng)時節(jié)點(diǎn)還沒完全掛,只是響應(yīng)超時,則嘗試將 Dead Master 加上全局鎖(flush tables with read lock),在從節(jié)點(diǎn)中選擇一個候選主節(jié)點(diǎn)作為新的主節(jié)點(diǎn),進(jìn)行數(shù)據(jù)補(bǔ)齊。
數(shù)據(jù)補(bǔ)齊之后,摘掉 Dead Master 的寫 VIP,并嘗試加到新的主節(jié)點(diǎn)上。將其他存活的節(jié)點(diǎn)進(jìn)行數(shù)據(jù)補(bǔ)齊,并重新掛載在新的主節(jié)點(diǎn)上。
主庫發(fā)生故障后,整個集群狀態(tài)變化如下:
mmm-manager 檢測到 master1 發(fā)生了故障,對數(shù)據(jù)進(jìn)行補(bǔ)齊之后,將寫 VIP 漂移到了 master2 上,應(yīng)用寫操作在新的節(jié)點(diǎn)上繼續(xù)進(jìn)行。
然而,MMM 架構(gòu)存在如下問題:
- VIP 的數(shù)量過多,管理困難(曾經(jīng)有一個集群是 1 主 6 從,共計 7 個 VIP)。某些情況下會導(dǎo)致集群大部分 VIP 同時丟失,很難分清節(jié)點(diǎn)上之前使用的是哪個 VIP。
- mmm-agent 過度敏感,容易導(dǎo)致 VIP 丟失。同時 mmm-agent 自身由于沒有高可用,一旦掛掉,會造成 mmm-manager 誤判,誤認(rèn)為 MySQL 節(jié)點(diǎn)異常。
- mmm-manager 存在單點(diǎn),一旦由于某些原因掛掉,整個集群就失去了高可用。
- VIP 需要使用 ARP 協(xié)議,跨網(wǎng)段、跨機(jī)房的高可用基本無法實(shí)現(xiàn),保障能力有限。
同時,MMM 是 Google 技術(shù)團(tuán)隊開發(fā)的一款比較老的高可用產(chǎn)品,在業(yè)內(nèi)使用的并不多,社區(qū)也不活躍,Google 很早就不再維護(hù) MMM 的代碼分支。
我們在使用過程中發(fā)現(xiàn)大量 Bug,部分 Bug 我們做了修改,并提交到開源社區(qū)。
MHA
針對于此,從 2015 年開始,美團(tuán)點(diǎn)評對 MySQL 高可用架構(gòu)進(jìn)行了改進(jìn),全部更新為 MHA,很大程度上解決了之前 MMM 遇到的各種問題。
MHA(MySQL Master High Availability)是由 Facebook 工程師 Yoshinori Matsunobu 開發(fā)的一款 MySQL 高可用軟件,從名字就可以看出,MHA 只負(fù)責(zé) MySQL 主庫的高可用。
當(dāng)主庫發(fā)生故障時,MHA 會選擇一個數(shù)據(jù)最接近原主庫的候選主節(jié)點(diǎn)(這里只有一個從節(jié)點(diǎn),所以該從節(jié)點(diǎn)即為候選主節(jié)點(diǎn))作為新的主節(jié)點(diǎn),并補(bǔ)齊和之前 Dead Master 差異的 Binlog。數(shù)據(jù)補(bǔ)齊之后,即將寫 VIP 漂移到新主庫上。
整個 MHA 的架構(gòu)如下(為簡單起見,只描述一主一從):
這里我們對 MHA 做了一些優(yōu)化,避免一些腦裂問題。
比如 DB 服務(wù)器的上聯(lián)交換機(jī)出現(xiàn)了抖動,導(dǎo)致主庫無法訪問,被管理節(jié)點(diǎn)判定為故障,觸發(fā) MHA 切換,VIP 被漂到了新主庫上。
隨后交換機(jī)恢復(fù),主庫可被訪問,但由于 VIP 并沒有從主庫上摘除,因此 2 臺機(jī)器同時擁有 VIP,會產(chǎn)生腦裂。
我們對 MHA Manager 加入了向同機(jī)架上其他物理機(jī)的探測,通過對比更多的信息來判斷是網(wǎng)絡(luò)故障還是單機(jī)故障。
MHA+Zebra(DAL)
Zebra(斑馬)是美團(tuán)點(diǎn)評基礎(chǔ)架構(gòu)團(tuán)隊開發(fā)的一個 Java 數(shù)據(jù)庫訪問中間件。
它是在 c3p0 基礎(chǔ)上包裝的美團(tuán)點(diǎn)評內(nèi)部使用的動態(tài)數(shù)據(jù)源,包括讀寫分離、分庫分表、SQL 流控等非常強(qiáng)的功能,它和 MHA 配合,成為了 MySQL 數(shù)據(jù)庫高可用的重要一環(huán)。
如下是 MHA+Zebra 配合的整體架構(gòu):
以主庫發(fā)生故障為例,處理邏輯有如下兩種方式:
- 當(dāng) MHA 切換完成之后,主動發(fā)送消息給 Zebra monitor,Zebra monitor 更新 ZooKeeper 的配置,將主庫上配置的讀流量標(biāo)記為下線狀態(tài)。
- Zebra monitor 每隔一段時間(10s ~ 40s)檢測集群中節(jié)點(diǎn)的健康狀況,一旦發(fā)現(xiàn)某個節(jié)點(diǎn)出現(xiàn)了問題,及時刷新 ZooKeeper 中的配置,將該節(jié)點(diǎn)標(biāo)記為下線。
一旦節(jié)點(diǎn)變更完成,客戶端監(jiān)聽到節(jié)點(diǎn)發(fā)生了變更,會立即使用新的配置重建連接,而老的連接會逐步關(guān)閉。
整個集群故障切換的過程如下(僅描述 Zebra monitor 主動探測的情況,第一種 MHA 通知請自行腦補(bǔ)^_^)。
由于該切換過程還是借助于 VIP 漂移,導(dǎo)致只能在同網(wǎng)段或者說同個二層交換機(jī)下進(jìn)行,無法做到跨網(wǎng)段或者跨機(jī)房的高可用。
為解決這個問題,我們對 MHA 進(jìn)行了二次開發(fā),將 MHA 添加 VIP 的操作去掉,切換完之后通知 Zebra monitor 去重新調(diào)整節(jié)點(diǎn)的讀寫信息(將 Write 調(diào)整為 new master 的實(shí) IP,將 Dead Master 的讀流量摘除)。
整個切換就完全去 VIP 化,做到跨網(wǎng)段、甚至跨機(jī)房切換,徹底解決之前高可用僅局限于同網(wǎng)段的問題。
上述切換過程就變成了如下圖:
然而,這種方式中的 MHA 管理節(jié)點(diǎn)是單點(diǎn),在網(wǎng)絡(luò)故障或者機(jī)器宕機(jī)情況下依然存在風(fēng)險。
同時,由于 Master-Slave 之間是基于 Binlog 的異步復(fù)制,也就導(dǎo)致了主庫機(jī)器宕機(jī)或者主庫無法訪問時,MHA 切換過程中可能導(dǎo)致數(shù)據(jù)丟失。
另外,當(dāng) Master-Slave 延遲太大時,也會給數(shù)據(jù)補(bǔ)齊這一操作帶來額外的時間開銷。
Proxy
除了 Zebra 中間件,美團(tuán)點(diǎn)評還有一套基于 Proxy 的中間件和 MHA 一起配合使用。
當(dāng) MHA 切換后,主動通知 Proxy 來進(jìn)行讀寫流量調(diào)整,Proxy 相比 Zebra 更加靈活,同時也能覆蓋非 Java 應(yīng)用場景。
缺點(diǎn)就是訪問鏈路多了一層,對應(yīng)的 Response Time 和故障率也有一定增加。
未來架構(gòu)設(shè)想
MHA 架構(gòu)依然存在如下兩個問題:
- 管理節(jié)點(diǎn)單點(diǎn)
- MySQL 異步復(fù)制中的數(shù)據(jù)丟失
針對于此,我們在部分核心業(yè)務(wù)上使用 Semi-Sync,可以保證 95% 以上場景下數(shù)據(jù)不丟失(依然存在一些極端情況下無法保障數(shù)據(jù)的強(qiáng)一致性)。
另外,高可用使用分布式的 Agent,在某個節(jié)點(diǎn)發(fā)生故障后,通過一定的選舉協(xié)議來選擇新的 Master,從而解決了 MHA Manager 的單點(diǎn)問題。
針對上述問題,我們研究了業(yè)界的一些領(lǐng)先的做法,簡單描述如下。
主從同步數(shù)據(jù)丟失
針對主從同步的數(shù)據(jù)丟失,一種做法是創(chuàng)建一個 Binlog Server,該 Server 模擬 Slave 接受 Binlog 日志,主庫每次的數(shù)據(jù)寫入都需要接收到 Binlog Server 的 ACK 應(yīng)答,才認(rèn)為寫入成功。
Binlog Server 可以部署在就近的物理節(jié)點(diǎn)上,從而保證每次數(shù)據(jù)寫入都能快速落地到 Binlog Server。
在發(fā)生故障時,只需要從 Binlog Server 拉取數(shù)據(jù)即可保證數(shù)據(jù)不丟失。
分布式 Agent 高可用
針對 MHA 管理節(jié)點(diǎn)單點(diǎn)問題,一種做法是讓 MySQL 數(shù)據(jù)庫集群中每個節(jié)點(diǎn)部署 Agent,當(dāng)發(fā)生故障時,每個 Agent 均參與選舉投票,選舉出合適的 Slave 作為新的主庫,防止只通過 Manager 來切換,去除 MHA 單點(diǎn)。
整個架構(gòu)如下圖所示:
MGB 結(jié)合中間件高可用
上述方式某種程度上解決了之前的問題,但是 Agent 和 Binlog Server 卻是新引入的風(fēng)險,同時 Binlog Server 的存在,也帶來了響應(yīng)時間上的額外開銷。
有沒有一種方式,能夠去除 Binlog Server 和 Agent,又能保證數(shù)據(jù)不丟失呢 ?答案當(dāng)然是有的。
最近幾年,MySQL 社區(qū)關(guān)于分布式協(xié)議 Raft 和 Paxos 非常火,社區(qū)也推出了基于 Paxos 的 MGR 版本的 MySQL,通過 Paxos 將一致性和切換過程下推到數(shù)據(jù)庫內(nèi)部,向上層屏蔽了切換細(xì)節(jié)。
架構(gòu)如下(以 MGR 的 single-primary 為例):
當(dāng)數(shù)據(jù)庫發(fā)生故障時,MySQL 內(nèi)部自己進(jìn)行切換。切換完成后將 topo 結(jié)構(gòu)推送給 Zebra monitor,Zebra monitor 進(jìn)行相應(yīng)的讀寫流量變更。
不過,該架構(gòu)存在與 Binlog Server 同樣的需要回復(fù)確認(rèn)問題,就是每次主庫數(shù)據(jù)寫入,都需要大多數(shù)節(jié)點(diǎn)回復(fù) ACK,該次寫入才算成功,存在一定的響應(yīng)時間開銷。
同時,每個 MGR 集群必須需要奇數(shù)個數(shù)(大于 1)的節(jié)點(diǎn),導(dǎo)致原先只需要一主一從兩臺機(jī)器,現(xiàn)在需要至少三臺,帶來一定的資源浪費(fèi)。
但不管怎么說,MGR 的出現(xiàn)無疑是 MySQL 數(shù)據(jù)庫又一次偉大的創(chuàng)新。
結(jié)語
本文介紹了美團(tuán)點(diǎn)評 MySQL 數(shù)據(jù)庫高可用架構(gòu)從 MMM 到 MHA+Zebra 以及 MHA+Proxy 的演進(jìn)歷程,同時也介紹了業(yè)界一些高可用的做法。
數(shù)據(jù)庫最近幾年的發(fā)展突飛猛進(jìn),數(shù)據(jù)庫的高可用設(shè)計上沒有完美的方案,只有不斷的突破和創(chuàng)新,我們也一直在這條路上探索更加優(yōu)秀的設(shè)計與更加完美的方案。
責(zé)任編輯:售電衡衡
-
碳中和戰(zhàn)略|趙英民副部長致辭全文
2020-10-19碳中和,碳排放,趙英民 -
兩部門:推廣不停電作業(yè)技術(shù) 減少停電時間和停電次數(shù)
2020-09-28獲得電力,供電可靠性,供電企業(yè) -
國家發(fā)改委、國家能源局:推廣不停電作業(yè)技術(shù) 減少停電時間和停電次數(shù)
2020-09-28獲得電力,供電可靠性,供電企業(yè)
-
碳中和戰(zhàn)略|趙英民副部長致辭全文
2020-10-19碳中和,碳排放,趙英民 -
深度報告 | 基于分類監(jiān)管與當(dāng)量協(xié)同的碳市場框架設(shè)計方案
2020-07-21碳市場,碳排放,碳交易 -
碳市場讓重慶能源轉(zhuǎn)型與經(jīng)濟(jì)發(fā)展并進(jìn)
2020-07-21碳市場,碳排放,重慶
-
兩部門:推廣不停電作業(yè)技術(shù) 減少停電時間和停電次數(shù)
2020-09-28獲得電力,供電可靠性,供電企業(yè) -
國家發(fā)改委、國家能源局:推廣不停電作業(yè)技術(shù) 減少停電時間和停電次數(shù)
2020-09-28獲得電力,供電可靠性,供電企業(yè) -
2020年二季度福建省統(tǒng)調(diào)燃煤電廠節(jié)能減排信息披露
2020-07-21火電環(huán)保,燃煤電廠,超低排放
-
四川“專線供電”身陷違法困境
2019-12-16專線供電 -
我國能源替代規(guī)范法律問題研究(上)
2019-10-31能源替代規(guī)范法律 -
區(qū)域鏈結(jié)構(gòu)對于數(shù)據(jù)中心有什么影響?這個影響是好是壞呢!