云數(shù)據(jù)庫高可用解決方案技術(shù)解析
高可用,英文翻譯為”High Availability”.
從字面上理解就是要做到服務(wù)的full-time的持續(xù)可用,但老實(shí)說,要做到full-time是不現(xiàn)實(shí)的,因?yàn)槟軌蛴绊懴到y(tǒng)服務(wù)可用性的因素實(shí)在是太多了,除了軟件BUG、硬件故障外還包括系統(tǒng)所依賴的一些第三方服務(wù)(如運(yùn)營(yíng)商提供的帶寬),甚至還包括天災(zāi)人禍等;因此我理解所謂的高可用意味著”更少的停服時(shí)間”,而工業(yè)界也有一套測(cè)量系統(tǒng)可用性的標(biāo)準(zhǔn),即大家所熟知的SLA(Service Level Agrement),也就是幾個(gè)9的可用性(如下表):
在工業(yè)應(yīng)用場(chǎng)景中,如當(dāng)下做在線服務(wù)的各大互聯(lián)網(wǎng)公司,號(hào)稱7*24小時(shí)的不間斷服務(wù),想想如果只是達(dá)到一個(gè)9的可用性將會(huì)是一種什么樣的災(zāi)難;而要做到5個(gè)9的可用性就意味著全年只有一次服務(wù)宕機(jī),而且得在5分鐘左右就恢復(fù),其中的難度也是不言而喻的,我想只是采用技術(shù)手段不足以做到,還需要通過一整套完備嚴(yán)謹(jǐn)?shù)墓こ坦芾矸婪都芭涮坠ぞ?、?yōu)秀工程運(yùn)維人員等。
云計(jì)算號(hào)稱互聯(lián)網(wǎng)公司的水和電,高可用猶如云服務(wù)商的生命線,而云數(shù)據(jù)庫作為該領(lǐng)域的一項(xiàng)重要服務(wù)更是接受著不同維度的考驗(yàn),因?yàn)樵贫顺汕先f個(gè)用戶數(shù)據(jù)庫實(shí)例所面臨的問題會(huì)更加五花八門。
下面將先介紹MySQL領(lǐng)域幾個(gè)典型的高可用解決方案,分析其中的關(guān)鍵技術(shù)及適用場(chǎng)景,并在此基礎(chǔ)上介紹和分享UDB的高可用方案。
一、高可用數(shù)據(jù)庫關(guān)鍵技術(shù)點(diǎn)
數(shù)據(jù)庫服務(wù)和很多工業(yè)服務(wù)在高可用技術(shù)方案是相通的,為了實(shí)現(xiàn)高可用首先實(shí)現(xiàn)服務(wù)的”冗余”,即服務(wù)的集群化,如果服務(wù)有冗余備份,宕機(jī)后還有其它備份服務(wù)(熱備和冷備)可以頂上,所以實(shí)現(xiàn)數(shù)據(jù)庫服務(wù)的”冗余”也是高可用數(shù)據(jù)庫的核心準(zhǔn)則;而有了”冗余”備份后還不夠,如果每次宕機(jī)都需要人工恢復(fù)切換至備份服務(wù),恢復(fù)時(shí)間得不到保證,同時(shí)人為的故障恢復(fù)過程中可能會(huì)引入新的風(fēng)險(xiǎn)(人為事故),從而降低了服務(wù)的可用性,因此必須還具備”自動(dòng)故障轉(zhuǎn)移”功能。而數(shù)據(jù)庫服務(wù)相比于其它系統(tǒng)的高可用,在以上兩個(gè)關(guān)鍵技術(shù)點(diǎn)的實(shí)現(xiàn)上會(huì)更加的困難,因?yàn)閭鹘y(tǒng)RDMS對(duì)數(shù)據(jù)和事務(wù)的持久性和穩(wěn)定性是要求非高的,從也提高了對(duì)冗余數(shù)據(jù)的一致性的要求和實(shí)現(xiàn)難度。
二、高可用MySQL典型解決方案
下圖是Oracle官方對(duì)MySQL幾種典型高可用方案及可用性的總結(jié),由于時(shí)間相對(duì)較早并且隨著近幾年分布式一致性協(xié)議在工業(yè)界的實(shí)踐和發(fā)展,MySQL高可用方案又有了全新的發(fā)展方向以及相對(duì)成熟的方案,下面將一并羅列和解析。
Mysql Replication 就是通過MySQL原生的復(fù)制技術(shù)來實(shí)現(xiàn)數(shù)據(jù)的冗余,該方案也是最易實(shí)現(xiàn)和通用的方案,相關(guān)的原理介紹網(wǎng)上介紹很多,這里不再詳細(xì)贅述,實(shí)現(xiàn)原理主要是通過2PC來實(shí)現(xiàn)本地BINLOG和本地?cái)?shù)據(jù)的一致性,并再此基礎(chǔ)上通過兩個(gè)線程(IO線程和SQL線程)來實(shí)現(xiàn)遠(yuǎn)端數(shù)據(jù)和本地?cái)?shù)據(jù)的同步,根據(jù)數(shù)據(jù)一致性程度不同復(fù)制技術(shù)又可以分為異步復(fù)制、半同步復(fù)制以及同步復(fù)制,另外在此冗余技術(shù)之上,一般會(huì)搭配使用MysqlProxy、keepalived、MHA等第三方軟件來實(shí)現(xiàn)自動(dòng)容災(zāi),此技術(shù)方案如果不做一定優(yōu)化,可用性一般不到2個(gè)9。
Mysql Fabric 是Oracle官方提供的一種Mysql高可用方案,通過數(shù)據(jù)分片下的讀寫分離模式,該方案的可用性達(dá)到2個(gè)9。
DRBD磁盤復(fù)制,分布式塊設(shè)備復(fù)制(Distributed Relicated Block Deivce,DRBD),是一種基于軟件、基于網(wǎng)絡(luò)的塊復(fù)制存儲(chǔ)解決方案,主要用于對(duì)服務(wù)器之間的磁盤、分區(qū)、邏輯卷等進(jìn)行數(shù)據(jù)鏡像,當(dāng)用戶將數(shù)據(jù)寫入本地磁盤時(shí),還會(huì)將數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)中另一臺(tái)主機(jī)的磁盤上,這樣的本地主機(jī)(主節(jié)點(diǎn))與遠(yuǎn)程主機(jī)(備節(jié)點(diǎn))的數(shù)據(jù)就可以保證實(shí)時(shí)同步,當(dāng)本地主機(jī)出現(xiàn)問題,遠(yuǎn)程主機(jī)上還保留著一份相同的數(shù)據(jù),可以繼續(xù)使用,保證了數(shù)據(jù)的安全,該方案缺點(diǎn)是IO性能影響嚴(yán)重,可用性不到3個(gè)9。
Solaris Clustering,該方案代表這另一種技術(shù)方向,即以共享存儲(chǔ)為基礎(chǔ),實(shí)現(xiàn)數(shù)據(jù)庫服務(wù)器和存儲(chǔ)設(shè)備的解耦,這樣數(shù)據(jù)庫服務(wù)器之間的冗余與數(shù)據(jù)無關(guān),而數(shù)據(jù)的冗余則通過SAN共享儲(chǔ)存或者分布式存儲(chǔ)系統(tǒng)來實(shí)現(xiàn),當(dāng)然Solaris Clustering除此之外還提供了操作系統(tǒng)、硬件等各個(gè)層面的監(jiān)控機(jī)制,該方案的可用性達(dá)到接近4個(gè)9,但是實(shí)現(xiàn)代價(jià)大,價(jià)格昂貴。
Mysql Cluster是官方提供的一個(gè)開源方案,其將MySQL的集群分為SQL節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn)通過一種內(nèi)存中的存儲(chǔ)引擎來實(shí)現(xiàn)自動(dòng)sharding和復(fù)制,雖然該方案號(hào)稱接近5個(gè)9的可用性,但是缺點(diǎn)也是很多,如對(duì)內(nèi)存消耗大,使用成本高,犧牲了過多的SQL語言特性,配置復(fù)雜等。
基于PAXOS分布式一致性協(xié)議的方案,Paxos 協(xié)議主要多數(shù)派投票的方式,來就分布式系統(tǒng)中某個(gè)值達(dá)成一致,該算法被業(yè)界認(rèn)為唯一的分布式一致性算法,包括其在內(nèi)衍生出來的分布式一致性算法(如Raft等)也在很多肯多開源分布式系統(tǒng)得到應(yīng)用。Paxos與MySQL相結(jié)合可以實(shí)現(xiàn)在分布式的MySQL數(shù)據(jù)庫最終一致性從而保證高可用,而使用分布式算法用來解決MySQL數(shù)據(jù)庫數(shù)據(jù)一致性的問題的方法,也越來越被人們所接受,一系列產(chǎn)品如PhxSQL、MariaDB Galera Cluster、Percona XtraDB Cluster等越來越多的被應(yīng)用到生產(chǎn)環(huán)境,而最近Oracle官方所推出的MySQL Group Replication的GA,更使其在Mysql高可用領(lǐng)域成為了一種民用技術(shù);因此使用分布式協(xié)議和多副本來解決數(shù)據(jù)庫一致性問題已經(jīng)成為了主流的方向。但是此類方案還出于初級(jí)階段,不夠成熟,同時(shí)分布式一致性協(xié)議由于網(wǎng)絡(luò)開銷的原因在性能上還有待提高和優(yōu)化。
三、 高可用數(shù)據(jù)庫案例分享--UDB
為了實(shí)現(xiàn)云數(shù)據(jù)庫服務(wù)的高可用,UDB基于半同步復(fù)制技術(shù)采用雙主的熱備架構(gòu),為了實(shí)現(xiàn)故障自動(dòng)轉(zhuǎn)移,并在此基礎(chǔ)上實(shí)現(xiàn)了Proxy模塊,該模塊不僅負(fù)責(zé)數(shù)據(jù)業(yè)務(wù)的轉(zhuǎn)發(fā),同時(shí)還監(jiān)控后端DB的健康狀況,雙主數(shù)據(jù)一致性檢測(cè),并在后端DB宕機(jī)情況下,在不影響數(shù)據(jù)一致性的情況下,完成數(shù)據(jù)業(yè)務(wù)切換,整個(gè)架構(gòu)及容災(zāi)過程如下圖:
也許從架構(gòu)上看很簡(jiǎn)單,一主一備的架構(gòu)沒有什么新意,但是深入到細(xì)節(jié)中會(huì)發(fā)現(xiàn)有很多問題和難點(diǎn),或者說這些問題都圍繞這一個(gè)目標(biāo),如何保證數(shù)據(jù)一致性。
普通的異步復(fù)制對(duì)數(shù)據(jù)庫性能影響小,但是主從數(shù)據(jù)一致性難以保證;強(qiáng)同步復(fù)制雖然保證了主從強(qiáng)一致,但是可用性很差;因此udb選擇了折中的方案即半同步復(fù)制,但只是簡(jiǎn)單的使用半同步復(fù)制還是不夠,通過分析半同步復(fù)制的過程和原理,會(huì)發(fā)現(xiàn)半同步復(fù)制會(huì)存在以下一些缺陷,下面將分析缺陷的同時(shí)介紹下udb的解決方案和策略:
1. 臨界事務(wù)問題?
什么是臨界事務(wù),臨界事務(wù)就是在宕機(jī)那個(gè)時(shí)間點(diǎn)主庫正在提交的事務(wù),這個(gè)事務(wù)可能已經(jīng)提交,可能已經(jīng)fsync到磁盤,但是確沒有同步到從庫中去,半同步復(fù)制對(duì)于臨界事務(wù)是沒法保證的,如下圖是myql5.7無損復(fù)制一次事務(wù)commit流程(udb基于次復(fù)制技術(shù)做了優(yōu)化):
如上圖,我們對(duì)5.7版本中的無損復(fù)制模式(默認(rèn)模式下)的半同步復(fù)制的主機(jī)commit做了細(xì)分,拆成7個(gè)可能crash的階段,考慮到雙機(jī)切換后可能會(huì)導(dǎo)致的數(shù)據(jù)丟失和數(shù)據(jù)一致性異常,我們對(duì)每個(gè)階段有如下分析:
- 在階段1,2,3發(fā)生了crash,由于主庫重啟后事務(wù)會(huì)回滾,binlog未發(fā)送到從庫,所以不會(huì)發(fā)生異常。
- 在階段4發(fā)生異常,由于主庫進(jìn)入了commit階段,但是binlog尚未發(fā)送到從庫。在主庫重啟后仍然會(huì)將這個(gè)事務(wù)發(fā)送到從機(jī)。
- 在階段5,6,7發(fā)生異常,由于從庫已經(jīng)收到了binlog,只要主庫重啟后即可達(dá)到主庫和備庫數(shù)據(jù)一致的效果。
通過以上分析,無損復(fù)制模式下只有在階段4發(fā)生宕機(jī)會(huì)導(dǎo)致恢復(fù)后雙主數(shù)據(jù)不一致,因?yàn)楫?dāng)在此階段發(fā)生宕機(jī),該事務(wù)并沒有發(fā)送至從庫,但是主庫已提交至Binlog和Redolog,如果此時(shí)業(yè)務(wù)切至從庫,主庫恢復(fù)后會(huì)繼續(xù)將事務(wù)commit并同步到從庫,但是由于從庫上已經(jīng)有了新事務(wù),很可能會(huì)和此事務(wù)產(chǎn)生沖突(如主鍵沖突),從而導(dǎo)致雙主數(shù)據(jù)不一致;為了解決此宕機(jī)時(shí)臨界事務(wù)問題,我們通過內(nèi)核層面在主庫重啟recovery階段作了如下調(diào)整:有選擇性的commit并復(fù)制到從庫部分事務(wù),回滾掉沒有同步到原從庫的事務(wù)及Truncate掉binlog中相應(yīng)的event,整個(gè)過程如下圖:
如上圖所示,主庫在恢復(fù)后,會(huì)向從庫或者proxy詢問從本庫同步過去的***一條事務(wù)的Binlog位置,并以此為基礎(chǔ)回滾掉該Binlog位置之后的臨界事務(wù)。
2. 半同步退化問題?
由于網(wǎng)絡(luò)抖動(dòng)以及從庫硬件故障等問題會(huì)導(dǎo)致半同步退化為異步,如果在此情況下主庫發(fā)生宕機(jī)并發(fā)生切換,會(huì)導(dǎo)致數(shù)據(jù)丟失,對(duì)于很多數(shù)據(jù)敏感的業(yè)務(wù)(如金融)后果是非常嚴(yán)重的;因此當(dāng)半同步復(fù)制退化,整個(gè)集群是不可以容災(zāi)切換業(yè)務(wù)的;但是如果主機(jī)宕機(jī)無法ssh登陸,我們又如何確定主從是否退化,從庫數(shù)據(jù)是否和主庫一致呢。
為了解決此問題,防止錯(cuò)誤的切換導(dǎo)致數(shù)據(jù)丟失,UDB通過在proxy和mysql之間以及主從之間增加鏈接通道,proxy和myql會(huì)用專門的線程通過此鏈接通道同步事務(wù)信息,如果主庫發(fā)生宕機(jī),從庫可以在本地緩存和遠(yuǎn)端proxy獲取同步事務(wù)信息,并使用該事務(wù)信息作為從機(jī)是否可以切換的依據(jù),如下圖:
同時(shí)為了提高可用性,應(yīng)對(duì)短時(shí)間網(wǎng)絡(luò)抖動(dòng)后造成雙主長(zhǎng)時(shí)間數(shù)據(jù)不一致,udb在網(wǎng)絡(luò)恢復(fù)后,會(huì)額外啟動(dòng)一個(gè)復(fù)制鏈路來追補(bǔ)落后的數(shù)據(jù),而原半同步復(fù)制鏈路繼續(xù)用于復(fù)制實(shí)時(shí)事務(wù),這樣不僅可以加快復(fù)制數(shù)據(jù)效率,而且避免了由于從庫負(fù)載過高永遠(yuǎn)恢復(fù)半同步的風(fēng)險(xiǎn)。
3. 如何保證proxy的高可用
通過以上問題及UDB相應(yīng)解決方案的分析,大家可以看出Proxy在整個(gè)架構(gòu)中扮演著極其重要的角色,不僅負(fù)責(zé)數(shù)據(jù)轉(zhuǎn)發(fā),同時(shí)為數(shù)據(jù)一致性和可用性提高保障;因此大家一定會(huì)問如果Proxy宕機(jī)怎么辦,為了解決Proxy高可用問題,UDB這邊對(duì)Proxy模塊也采用了一主一備模式,如下圖:
當(dāng)圖中左路主Proxy宕機(jī)后,ProxyMaster模塊會(huì)觸發(fā)容災(zāi)處理過程,此時(shí)ProxyMaster會(huì)將虛擬IP重新綁定至Proxy(backup)并自動(dòng)啟動(dòng),啟動(dòng)后Proxy(backup)會(huì)重新鏈路至原MasterDB,以保證業(yè)務(wù)不間斷,而ProxyMaster模塊通過ZK服務(wù)分布在多個(gè)服務(wù)器上,有效的保證了Proxy的可用性。
當(dāng)然除了該雙主技術(shù)架構(gòu)外,為了保障服務(wù)的高可用,UDB在運(yùn)維監(jiān)控等層面也做了很多工作,通過對(duì)從硬件、操作系統(tǒng)、數(shù)據(jù)庫以及網(wǎng)絡(luò)等各個(gè)層面的不間斷監(jiān)控,從而***程度的及時(shí)捕獲和恢復(fù)數(shù)據(jù)庫服務(wù);同時(shí)UDB通過自研的大型數(shù)據(jù)庫備份系統(tǒng),能夠應(yīng)對(duì)各種級(jí)別的宕機(jī)故障后的數(shù)據(jù)恢復(fù),從而保障了用戶數(shù)據(jù)的安全可靠性。
【本文是51CTO專欄機(jī)構(gòu)作者“大U的技術(shù)課堂”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)(ucloud2012)聯(lián)系作者】