張晨東,郭進(jìn)偉,劉柏眾,儲佳佳,周敏奇,錢衛(wèi)寧
(華東師范大學(xué)數(shù)據(jù)科學(xué)與工程研究院,上海 200062)
數(shù)據(jù)庫管理系統(tǒng)是存儲和訪問具有內(nèi)在關(guān)系的數(shù)據(jù)的系統(tǒng)軟件,例如DB2,Oracle,SQLServer等數(shù)據(jù)庫系統(tǒng),它們被廣泛應(yīng)用于銀行、商品交易、電信、電力等對可用性和可靠性要求非常高的領(lǐng)域,在生產(chǎn)和生活中起著至關(guān)重要的作用[1].
隨著移動互聯(lián)網(wǎng)的普及和發(fā)展,數(shù)據(jù)庫的數(shù)據(jù)量和訪問量呈指數(shù)級增長,傳統(tǒng)數(shù)據(jù)庫已難以滿足高并發(fā)、海量存儲的需求.因此許多互聯(lián)網(wǎng)公司將高可擴(kuò)展的分布式技術(shù)引入到數(shù)據(jù)庫系統(tǒng)中,研發(fā)出許多分布式數(shù)據(jù)庫系統(tǒng),例如Google的Bigtable[2],Spanner[3],Yahoo!的Dynamo[4]系統(tǒng)等.同時一批開源的NoSQL分布式數(shù)據(jù)庫也逐漸開始流行起來,例如HBase、MongoDB等,這些數(shù)據(jù)庫系統(tǒng)通過分布式的數(shù)據(jù)存儲機(jī)制保證了數(shù)據(jù)的可靠性和可擴(kuò)展性,使用了一些常見的容錯機(jī)制來保證系統(tǒng)的可用性.
技術(shù)發(fā)展的同時,信息安全也越來越被人們重視.作為存取數(shù)據(jù)的基礎(chǔ)軟件設(shè)施,數(shù)據(jù)庫管理系統(tǒng)在金融、政府等機(jī)構(gòu)的信息系統(tǒng)中處于至關(guān)重要的地位.然而數(shù)據(jù)庫系統(tǒng)產(chǎn)品的市場長期被國外壟斷,在信息安全方面存在著巨大的隱患,這種現(xiàn)狀促使國產(chǎn)軟件的發(fā)展上升為了國家戰(zhàn)略[5].
在這樣的市場需求和國家戰(zhàn)略的背景下,阿里巴巴集團(tuán)推出了一款支持海量數(shù)據(jù)存儲的高性能分布式數(shù)據(jù)庫系統(tǒng)OceanBase[6].它實現(xiàn)了數(shù)千億條記錄、數(shù)百TB數(shù)據(jù)上的跨行跨表事務(wù),能滿足當(dāng)前海量存儲需求的應(yīng)用,在可擴(kuò)展性、可用性和數(shù)據(jù)一致性方面都有非常好的表現(xiàn),并且已經(jīng)成功應(yīng)用到了阿里集團(tuán)內(nèi)部很多業(yè)務(wù)系統(tǒng)中.OceanBase的高可用性并沒有依賴于底層的高可用硬件,而是采用了價格低廉的普通PC服務(wù)器,在軟件層面上實現(xiàn)了系統(tǒng)內(nèi)部故障對外部使用者不可見,這種方式可以在不犧牲強一致性和高可用性的情況下有一個低成本的使用方案[7].
OceanBase最新的開源版本(0.4.2)有兩種集群部署模式:單集群模式和多集群模式.單集群模式下所有的機(jī)器都必須在一個機(jī)房內(nèi),它沒有防范區(qū)域性自然災(zāi)害的能力.多集群模式下,各個集群可以部署在不同地區(qū)的機(jī)房內(nèi),具有容災(zāi)的能力,但這種部署模式的可用性并不高.當(dāng)主集群出現(xiàn)故障導(dǎo)致系統(tǒng)不可用時,必須通過人工介入的方式來將備集群切換為主集群.即使人工介入了也有可能發(fā)生由于日志不一致而導(dǎo)致的主備集群切換失敗的情況,這是由于主備集群間的不可靠日志同步策略導(dǎo)致的.
針對OceanBase的多集群模式的可用性不高的缺陷,本文基于Raft一致性協(xié)議[8],設(shè)計并實現(xiàn)了一些功能來提高它的可用性:
①實現(xiàn)了基于日志時間戳的選主協(xié)議,使之適用于OceanBase的使用場景;
②實現(xiàn)了自動切換主備集群的功能,當(dāng)系統(tǒng)得到選舉結(jié)果后,能夠?qū)崟r感知到主備集群的狀態(tài),從而自動切換主備集群,保證了數(shù)據(jù)庫服務(wù)的持續(xù)可用性;
③設(shè)計并實現(xiàn)了基于QUORUM策略[9]的日志強同步技術(shù),在日志同步過程中兼顧了同步日志的效率和數(shù)據(jù)的可靠性,在多集群的部署模式下日志同步能夠保證集群的異常恢復(fù)機(jī)制,最大化整個系統(tǒng)的可用性,并且保證了在異?;謴?fù)的過程中數(shù)據(jù)的一致性和完整性;
實驗證明基于日志時間戳的選主協(xié)議以及集群切換過程是正確且高效的,日志同步能夠保證數(shù)據(jù)的完整性和一致性.
本文第一部分介紹了傳統(tǒng)數(shù)據(jù)庫高可用方案以及OceanBase的架構(gòu)和相關(guān)一致性算法背景.第二部分介紹了選主協(xié)議實現(xiàn)、主備集群切換的實現(xiàn)以及UpdateServer的日志強同步的實現(xiàn).第三部分對這些已實現(xiàn)的功能進(jìn)行測試實驗.第四部分是本文的總結(jié)以及對未來的發(fā)展方向的闡述.
可用性是指系統(tǒng)在面對各種異常時依然可以提供正常服務(wù)的能力.?dāng)?shù)據(jù)庫系統(tǒng)一般采用冗余硬件和數(shù)據(jù)的策略來實現(xiàn)高可用性.然而,數(shù)據(jù)一致性問題隨之產(chǎn)生.以下將分三個部分介紹本文的相關(guān)工作.
作為一個典型的傳統(tǒng)數(shù)據(jù)庫,Oracle提供了以下兩種高可用解決方案[10]:真正應(yīng)用集群(Real Application Cluster,RAC)[11],數(shù)據(jù)衛(wèi)士(Data Guard,DG)[12-13].
在RAC方案中,為了達(dá)到最高級別的服務(wù)器保護(hù)模式,一般有兩臺以上的服務(wù)器架構(gòu)在共享存儲設(shè)備之上,所有服務(wù)器均可直接訪問共享存儲中的數(shù)據(jù).這種方式使得在低成本服務(wù)器上構(gòu)建高可用性數(shù)據(jù)庫系統(tǒng)成為可能,但是RAC方案的缺陷在于系統(tǒng)的可用性受制于共享存儲的可用性.
在DG方案中,一個主服務(wù)器提供服務(wù),多個備服務(wù)器作為熱備份,主服務(wù)器需要將日志數(shù)據(jù)實時同步到備服務(wù)器上.DG方案提供了三種數(shù)據(jù)保護(hù)模式:
(1)最大保護(hù)模式:任何事務(wù)日志必須先成功同步到所有備服務(wù)器上,最后才會在主服務(wù)器上執(zhí)行成功,然后應(yīng)答客戶端成功;
(2)最高性能模式:任何事務(wù)只需在主服務(wù)器上執(zhí)行成功,就可以應(yīng)答客戶端成功;
(3)最大可用模式:最大可用模式介于前兩者之間,在正常情況下,它和最大保護(hù)模式一樣,但一旦備服務(wù)器出現(xiàn)故障,就立即切換成最高性能模式,但主服務(wù)器不會關(guān)閉.
在最大保護(hù)模式下,當(dāng)備服務(wù)器與主服務(wù)器間的網(wǎng)絡(luò)出現(xiàn)故障時,系統(tǒng)將無法提供服務(wù),失去可用性.在最高性能模式下,主備服務(wù)器之間的數(shù)據(jù)無法保證一致,當(dāng)備服務(wù)器切換為主服務(wù)器時,無法保證可靠性.在最大可用模式下,當(dāng)主服務(wù)器出現(xiàn)故障時,備服務(wù)器無法保證數(shù)據(jù)的強一致性.
不同于傳統(tǒng)的數(shù)據(jù)庫,OceanBase是在分布式的網(wǎng)絡(luò)環(huán)境下實現(xiàn)了高可用性[14-15].
根據(jù)系統(tǒng)中的功能和角色不同,可以將OceanBase分為四個模塊:主控服務(wù)器(Root-Server)、更新服務(wù)器(UpdateServer)、基線服務(wù)器(ChunkServer)以及合并服務(wù)器(MergeServer).各個模塊通過網(wǎng)絡(luò)傳輸數(shù)據(jù),其中RootServer負(fù)責(zé)集群中的機(jī)器管理和數(shù)據(jù)分布的管理,UpdateServer存儲增量數(shù)據(jù),ChunkServer存儲基線數(shù)據(jù),MergeServer負(fù)責(zé)SQL解析和執(zhí)行并對外提供服務(wù).
在OceanBase系統(tǒng)中,增量數(shù)據(jù)存儲在UpdateServer的內(nèi)存中,基線數(shù)據(jù)存儲在ChunkServer的磁盤上,當(dāng)增量數(shù)據(jù)達(dá)到一定閾值或者在每天的固定時刻會發(fā)生數(shù)據(jù)合并,將增量數(shù)據(jù)合并到基線數(shù)據(jù)上.這種將基線數(shù)據(jù)和增量數(shù)據(jù)分離開的方式減少了寫放大對系統(tǒng)性能的影響,也提高了數(shù)據(jù)的可靠性和系統(tǒng)的可用性[6].
OceanBase可以部署為單集群模式,也可以部署為多集群模式.當(dāng)OceanBase部署為多集群模式時,如圖1所示,這些集群可以部署在不同地區(qū)的機(jī)房中,在發(fā)生自然災(zāi)害或者整個機(jī)房發(fā)生停電等大規(guī)模區(qū)域性故障時,仍然可以保證數(shù)據(jù)的安全和數(shù)據(jù)庫服務(wù)的可用性.在多集群模式下,有一個主集群和多個備集群,每個集群中可以有一主一備兩個RootServer和UpdateServer保證單集群內(nèi)的可用性.主集群可以對外提供強一致性的查詢服務(wù),備集群也可以對外提供查詢服務(wù),但是只能提供弱一致性的查詢服務(wù).多集群在運行的時候,主集群一旦無法提供服務(wù),需要通過人工手動的方式將備集群切換為主集群.這種人工手動切換的方式風(fēng)險大,耗時長,不能保證系統(tǒng)的持續(xù)可用性.
圖1 OceanBase多集群模式的系統(tǒng)架構(gòu)Fig.1 The system architecture of OceanBase under multi-clusters
數(shù)據(jù)一致性是指各數(shù)據(jù)副本的數(shù)據(jù)總是一致的,表現(xiàn)在同一客戶端下,讀操作是否總能讀取到最新完成的寫操作結(jié)果.而在分布式系統(tǒng)中,數(shù)據(jù)的一致性尤為重要.為此,許多研究者為解決分布式環(huán)境下數(shù)據(jù)一致性問題,針對性地提出多種算法,其中較為典型的有Paxos一致性算法和Raft一致性算法.
(1)Paxos一致性算法
Paxos算法[16]是Leslie Lamport于1990年提出的一種基于消息傳遞模型且具有高度容錯特性的一致性算法,目的是解決如何在一個不可靠的網(wǎng)絡(luò)環(huán)境和不可靠的節(jié)點之間就某個值達(dá)成一致.在一個分布式數(shù)據(jù)庫系統(tǒng)中,不考慮消息傳遞過程中可能出現(xiàn)的拜占庭錯誤,如果各個節(jié)點的初始狀態(tài)是一致的,在經(jīng)過相同的操作序列后,它們最終一定能達(dá)到一致的狀態(tài).為了保證每個節(jié)點都能經(jīng)過相同的操作序列,每執(zhí)行一條操作指令,都要使用一次Paxos算法來達(dá)成一致.
上述描述的是Basic Paxos.除此之外,還有很多基于Paxos的變種,如Multi-Paxos[17],Cheap Paxos[18],F(xiàn)ast Paxos[19]等,它們都對Basic Paxos算法進(jìn)行了不同程度的優(yōu)化.Pax-os算法雖然能解決分布式環(huán)境下多個節(jié)點就某個值達(dá)成一致的問題,但是算法本身的邏輯過于復(fù)雜,很難被人理解,實現(xiàn)十分困難.
(2)Raft一致性算法
針對Paxos難于被理解的問題,斯坦福大學(xué)的Diego Ongaro和John Ousterhout提出了一個管理日志復(fù)制的一致性算法Raft[7],它是由Paxos算法演化而來的,它的首要設(shè)計目標(biāo)就是為了使得它易于理解和實現(xiàn).
為了加強算法的可理解性,Raft將達(dá)成一致性的關(guān)鍵步驟分離開,例如Leader的選舉、日志復(fù)制、安全性保證等這些關(guān)鍵步驟,通過減少需要考慮到的狀態(tài)來保證了更強的一致性.Raft的可理解性經(jīng)過實踐驗證是有效果的,它能很容易被理解和實現(xiàn).
由于OceanBase開源至今已先后發(fā)布多個版本,未來可能還會有新的版本發(fā)布,為避免混亂,本文中所提及的OceanBase版本特定為0.4.2版本.該版本的OceanBase系統(tǒng)沒有自動選主及自動切換主備集群的功能,并且日志的同步策略會引起主備切換發(fā)生數(shù)據(jù)不一致的問題.
OceanBase為了能夠支持異地容災(zāi),提供了多集群部署模式.當(dāng)主集群出現(xiàn)故障時,需要選擇一個備集群切換為主集群,此過程通過人工判斷,一般選取數(shù)據(jù)最新的為主集群.由于切換過程是由人工手動去執(zhí)行的,這是一個較為耗時并且有操作失誤風(fēng)險的過程.
OceanBase主備集群的日志同步策略會引起手動切換主備不成功的問題.OceanBase的數(shù)據(jù)分為基線數(shù)據(jù)和增量數(shù)據(jù),由于基線數(shù)據(jù)是由增量數(shù)據(jù)轉(zhuǎn)換得到的,所以O(shè)ceanBase要保證全量數(shù)據(jù)的同步只需實時同步增量數(shù)據(jù)即可,由主集群中的UpdateServer將增量數(shù)據(jù)以日志的形式發(fā)送到各個備集群中UpdateServer上.日志同步策略類似于Oracle Data-Guard方案中的最大性能模式,同步日志時并不需要保證任何一個備UpdateServer回放日志成功,這種日志同步策略會使主UpdateServer的日志數(shù)據(jù)經(jīng)常會超前于備UpdateServer的日志數(shù)據(jù),當(dāng)主UpdateServer發(fā)生故障宕機(jī)時,備UpdateServer的數(shù)據(jù)會落后于發(fā)生宕機(jī)的UpdateServer,從備機(jī)中重新選出的主UpdateServer必然會丟失一部分?jǐn)?shù)據(jù),此時如果重啟原先宕機(jī)的UpdateServer,就會發(fā)生數(shù)據(jù)不一致的問題.
OceanBase在設(shè)計多集群部署模式時并沒有考慮到主集群不可用時人工介入的不足,日志同步的模式也會導(dǎo)致主備集群的切換會發(fā)生數(shù)據(jù)不一致的問題,因此OceanBase無法應(yīng)用于對可用性要求較高的場景.考慮到OceanBase本身架構(gòu)的特點,并結(jié)合Raft算法的思想,本文實現(xiàn)了:(1)基于日志時間戳的選舉協(xié)議;(2)基于QUORUM策略的日志強同步技術(shù).
為了提高OceanBase的可用性,我們在深入了解OceanBase系統(tǒng)架構(gòu)的基礎(chǔ)上,借鑒了Raft算法的思想,設(shè)計并實現(xiàn)了如下的一些功能:
(1)基于日志時間戳的選主協(xié)議,使它能夠在多集群模式下的實現(xiàn)成為可能;
(2)全自動化的集群切換功能,當(dāng)Raft選舉出新的主后能夠快速自動切換主備集群;
(3)基于QUORUM策略的日志強同步技術(shù),保證了數(shù)據(jù)的完整性和可靠性.
在OceanBase 0.4.2版本的基礎(chǔ)上,本文設(shè)計了如圖2所示的集群架構(gòu),并實現(xiàn)了如圖3所示的集群自動切換過程.
圖2 多集群架構(gòu)Fig.2 The architecture of multi-clusters
圖3 集群切換過程Fig.3 The process of clusters-switching
在圖2所示的多集群架構(gòu)中,每個集群中有且僅有一個RootServer和一個UpdateServer,并且多集群中只有一個主集群.其中在主集群中的RootServer和UpdateServer都是主機(jī)的角色,備集群中的RootServer和UpdateServer都是備機(jī)的角色.
主備集群中的所有RootServer之間通過選舉協(xié)議保持始終只有一個主RootServer存在,當(dāng)主機(jī)發(fā)生故障時會有一個新的主RootServer被選舉出來,并發(fā)生集群角色的相應(yīng)切換過程(圖3).切換過程中的數(shù)據(jù)一致性和可靠性是由日志強同步來保證的.
為了保證系統(tǒng)的持續(xù)可用性,多集群模式下必須有一個主集群存在,當(dāng)主集群出現(xiàn)問題不可訪問時,應(yīng)當(dāng)有一個新的主集群能夠快速被選出來并提供服務(wù),這就需要通過選舉過程的一致性算法來實現(xiàn).我們選擇Raft一致性協(xié)議算法作為基礎(chǔ),對它進(jìn)行了定制,使它適用于OceanBase系統(tǒng),在RootServer模塊中實現(xiàn)了基于日志時間戳的選舉功能.
基于Raft一致性協(xié)議中的描述,我們?yōu)槊總€RootServer指定以下三種角色的其中之一:領(lǐng)導(dǎo)者(Leader),跟隨者(Follower),候選者(Candidate)[7].領(lǐng)導(dǎo)者是全局唯一的,包含領(lǐng)導(dǎo)者的集群就是主集群,在這個集群中的UpdateServer是主UpdateServer,并且是全局唯一的主UpdateServer,它是所有集群中唯一能夠接受寫操作的UpdateServer.跟隨者能夠接收領(lǐng)導(dǎo)者發(fā)送過來的日志,或者給滿足條件的候選者投票.候選者會主動發(fā)起選舉,角逐領(lǐng)導(dǎo)者的角色,當(dāng)跟隨者經(jīng)過了隨機(jī)等待時間后仍然沒有選出主,則它會將自己變?yōu)楹蜻x者,并向其他節(jié)點發(fā)送拉票請求.
當(dāng)RootServer剛啟動時,它的選舉模塊的功能不會開啟,必須通過人工手動開啟或者通過接收其他RootServer的選舉廣播消息來開啟,可以由數(shù)據(jù)庫管理員來決定第一次啟動時主所在的機(jī)器,便于管理員的管理.當(dāng)所有的RootServer都是剛啟動的狀態(tài),此時它們的選舉模塊都是被屏蔽的,并且沒有主RootServer存在,這時需要人工手動指定主RootServer來打開所有的RootServer的選舉模塊功能.在此之后若有RootServer發(fā)生故障重啟,不論它重啟之前是主RootServer還是備RootServer,都會接收到其他的RootServer的廣播消息,從而開啟選舉功能.
只有選舉功能是開啟的RootServer才能進(jìn)行正常的選舉過程.選舉的流程與Raft一致性算法中描述的相同,每個跟隨者必須先各自隨機(jī)等待一段時間才能發(fā)起選舉,這是為了減小選舉沖突導(dǎo)致選舉失敗的概率.當(dāng)跟隨者在這段時間內(nèi)沒有收到主RootServer的廣播信息,那么它會變?yōu)楹蜻x者向其他RootServer發(fā)起投票,當(dāng)接收到選票數(shù)超過半數(shù)則當(dāng)選為領(lǐng)導(dǎo)者,否則重新變?yōu)楦S者.與Raft算法不同的是,其他RootServer接收到投票請求時會比較UpdateServer的最大日志時間戳,以此作為條件來判斷是否同意該候選者成為領(lǐng)導(dǎo)者.在每個集群中的UpdateServer上都會記錄最新數(shù)據(jù)的日志時間戳,時間戳越大表示數(shù)據(jù)越新,若候選者的最大日志時間戳大于自己的最大日志時間戳,則表示候選者的數(shù)據(jù)比自己的數(shù)據(jù)更新,同意該投票請求,若候選者的最大日志時間戳小于自己的最大日志時間戳,表示候選者的數(shù)據(jù)舊于自己的數(shù)據(jù),則拒絕該投票請求.
當(dāng)一個節(jié)點成為領(lǐng)導(dǎo)者之后,它和其他每個節(jié)點之間都會維護(hù)一份租約信息,包括它自己,在租約快要到期的時候會給每個節(jié)點續(xù)約.在這個租約有效期內(nèi)跟隨者會一直認(rèn)為該領(lǐng)導(dǎo)者是有效的,如果超過了這個租約有效期并且一直未成功續(xù)約,可能是由于領(lǐng)導(dǎo)者宕機(jī)、跟隨者宕機(jī)或者是連接的網(wǎng)絡(luò)出現(xiàn)中斷故障等原因造成的.如果是第一種情況,領(lǐng)導(dǎo)者宕機(jī),跟隨者會隨機(jī)延遲一段時間然后重新發(fā)起選主.如果是第二種情況,跟隨者宕機(jī),這時領(lǐng)導(dǎo)者會檢查當(dāng)前仍然在線的跟隨者的數(shù)量,若少于一半就放棄主的身份,與其他在線的跟隨者節(jié)點重新選主.如果是第三種情況,網(wǎng)絡(luò)連接出現(xiàn)中斷,這時領(lǐng)導(dǎo)者會在自己與自己的租約時間到期后檢查當(dāng)前和它保持在線的跟隨者數(shù)量是否超過半數(shù),如果少于半數(shù)則自動放棄主的身份,重新選主.
如圖4所示為三集群中使用UpdateServer上的最大日志時間戳為條件進(jìn)行選主的過程,其中Tmax-log-1<Tmax-log-2<Tmax-log-3.集群2的RootServer的隨機(jī)等待時間首先 到 達(dá),它 會發(fā)起選舉,由于Tmax-log-2<Tmax-log-3,集 群3的RootServer會拒絕它的拉票請求,從而集群2的RootServer從候選者轉(zhuǎn)變?yōu)楦S者.再經(jīng)過一個隨機(jī)的等待時間后,集群3的RootServer再成為候選者發(fā)起投票,由于其中Tmax-log-1<Tmax-log-2<Tmax-log-3,從而集群3的RootServer當(dāng)選為領(lǐng)導(dǎo)者,它會將自己的信息通知給集群1和集群2的RootServer,并在這之后與這兩個RootServer一直保持租約.
圖4 Raft一致性協(xié)議選主過程Fig.4 The process of Raft election
RootServer中選舉模塊完成選主后,會更改當(dāng)前RootServer的角色,當(dāng)角色發(fā)生變化時系統(tǒng)就會進(jìn)行相應(yīng)的集群角色切換,此小節(jié)內(nèi)容介紹在選舉模塊角色發(fā)生變化時主備集群切換的過程.
多集群部署模式下每個集群也會有自己的角色,可以是主集群角色(OBI_M(jìn)ASTER)、備集群角色(OBI_SLAVE)或者初始集群角色(OBI_INIT).其中主集群是唯一的,它能提供強一致性的查詢服務(wù);備集群可以有多個,它們只能提供弱一致性的查詢服務(wù);初始化集群不能提供任何查詢服務(wù).
選舉模塊中的角色變化會引起集群角色的變化,進(jìn)而調(diào)起集群切換的流程.當(dāng)所有的RootServer都是處于剛啟動的狀態(tài)時,在選舉模塊中每個RootServer標(biāo)記的角色都是跟隨者,它們的集群角色都是OBI_INIT,必須通過人工指定選舉模塊角色為領(lǐng)導(dǎo)者,這時每個集群都會發(fā)生集群角色的改變,集群角色從OBI_INIT改變?yōu)镺BI_M(jìn)ASTER或者OBI_SLAVE.RootServer的主線程每隔10 ms檢查一次當(dāng)前的選舉模塊角色是否發(fā)生變化,一旦發(fā)生改變,相當(dāng)于集群角色改變,進(jìn)而引起集群的切換.
為了銜接選舉模塊角色變化與集群切換流程,我們使用三個狀態(tài)來標(biāo)記RootServer所處的狀態(tài):初始化狀態(tài)(INIT),選舉進(jìn)行狀態(tài)(DURING_ELECTION),有主狀態(tài)(AFTER_ELECTION).
以上三個狀態(tài)之間的遷移關(guān)系如圖5所示:
(1)初始化狀態(tài)是指RootServer啟動直到選舉線程的選舉功能被開啟這段時間所處的狀態(tài);
(2)選舉進(jìn)行狀態(tài)是指在選舉線程的選舉功能啟用的情況下無領(lǐng)導(dǎo)者的狀態(tài);
(3)有主狀態(tài)是指選舉線程選出領(lǐng)導(dǎo)者,并且它與其他跟隨者保持著租約,領(lǐng)導(dǎo)者可能是自己也可能是其他RootServer.
圖5 集群切換的狀態(tài)遷移圖Fig.5 The state transition diagram of clusters-switching
RootServer啟動后的狀態(tài)是初始化狀態(tài),它會等待領(lǐng)導(dǎo)者的廣播或者被人工手動指定為領(lǐng)導(dǎo)者,然后進(jìn)入有主狀態(tài).
系統(tǒng)中有主之后,每個RootServer都會從選舉進(jìn)行狀態(tài)轉(zhuǎn)換為有主狀態(tài).在接下來的過程中,如果選舉模塊角色沒有發(fā)生變化,則集群一直保持原來的狀態(tài),不會發(fā)生切換;如果發(fā)生了變化,則會發(fā)生集群角色的變化,并引發(fā)主備集群切換,主備集群切換過程可以分為兩種:①主集群→備集群;②備集群→主集群.
主集群切換為備集群的時候,主RootServer首先將自己的集群角色變?yōu)閭浼航巧?,再將?dāng)前集群中UpdateServer的集群角色變?yōu)閭浼航巧?/p>
備集群切換為主集群的時候,新的主RootServer首先會將原來的主RootServer設(shè)定為備集群角色,然后將自己成為主RootServer的信息通知給其他所有在線的RootServer,然后再分別修改它們映射到內(nèi)部表中集群信息、配置信息,這些信息是集群內(nèi)部的所有server在運行過程都需要用到的.
集群切換成功后OceanBase java客戶端會感知到集群發(fā)生切換,但是用戶卻不會發(fā)覺,因為在OceanBase java客戶端內(nèi)部實現(xiàn)了負(fù)載均衡算法,它會通過集群之間的流量控制將原主集群中的所有流量全部切換至新主集群上,這樣用戶就不會發(fā)覺主集群發(fā)生了切換,從而實現(xiàn)了持續(xù)可用性.
主集群是唯一能夠接受增量數(shù)據(jù)的集群,當(dāng)主集群出現(xiàn)故障時,整個系統(tǒng)將處于不可用的狀態(tài),因此需要從備集群中選出一個作為新的主集群,而新選出的主集群要保證與舊集群的數(shù)據(jù)一致性,才能繼續(xù)對外提供服務(wù).
OceanBase0.4.2采用了最大可用模式進(jìn)行日志同步,即在網(wǎng)絡(luò)正常時保證主備集群數(shù)據(jù)的一致性.但該日志同步方式無法保證備集群中的數(shù)據(jù)一定與主集群一致,當(dāng)系統(tǒng)出現(xiàn)主備切換時,可能導(dǎo)致部分?jǐn)?shù)據(jù)的丟失.為了避免該問題,高可用方案中的日志同步采用了QUORUM策略,即主集群將日志發(fā)送到包括自己在內(nèi)的所有集群,僅當(dāng)收到半數(shù)以上響應(yīng)后才能提交該日志對應(yīng)的事務(wù),如圖6所示.
采用QUORUM策略日志強同步的具體步驟如下:
(1)主集群中的UpdateServer(主UpdateServer)生成一條日志,將這條日志放入預(yù)提交隊列中,用異步的方式發(fā)送到所有備集群中的UpdateServer(備UpdateServer)上;
(2)每個備UpdateServer接收到日志之后將該日志放入回放線程的工作隊列中,同時會回復(fù)一個當(dāng)前集群上已經(jīng)成功刷入磁盤的最大日志號返回給主UpdateServer;
(3)主UpdateServer接收到這個最大日志號后,判斷該日志號之前的日志是否滿足QUORUM策略,如果滿足則從預(yù)提交隊列中取出該日志號之前對應(yīng)的事務(wù),并將該事務(wù)成功提交,否則繼續(xù)等待后續(xù)的同步回復(fù)消息.
圖6 日志同步策略Fig.6 The policy of log synchronization
UpdateServer在發(fā)生故障重啟后,日志回放的策略設(shè)計如下:
主UpdateServer根據(jù)備UpdateServer返回的最大日志號進(jìn)行比較,得到可以提交的日志號,稱之為已提交點,該點之前的所有日志能夠確保在多數(shù)派的集群中都是一致的,主UpdateServer會將已提交點存儲到本地磁盤上.若當(dāng)前的主UpdateServer宕機(jī)重啟后,根據(jù)重啟后所在集群的角色來決定回放日志的策略.如果集群角色為主集群,則將本地所有日志全部回放;如果是備集群,回放本地日志時只需回放本地日志到已提交點,該點之后的日志從新主UpdateServer上拉取,保證了數(shù)據(jù)的一致性.
圖7 UpdateServer重啟后回放日志的策略Fig.7 The policy of replaying logs after UpdateServer restart
如圖7所示為當(dāng)所有的UpdateServer都宕機(jī)重啟后,新的主UpdateServer被選舉出來,各UpdateServer的重放日志的策略.新的主UpdateServer和所有的備UpdateServer都是重放所有本地日志.原來的主UpdateServer重啟后變?yōu)閭?,它會重放本地日志到它記錄的已提交點的位置,后續(xù)的日志從新的主UpdateServer上拉?。?/p>
測試使用的OceanBase是在OceanBase 0.4.2上經(jīng)過我們優(yōu)化的版本,包括Raft選舉模塊功能的實現(xiàn),集群主備切換實現(xiàn)以及日志強同步功能的實現(xiàn).測試環(huán)境有兩套環(huán)境,一套是三集群的OceanBase系統(tǒng),另一套是五集群的OceanBase系統(tǒng).每個集群中有四臺服務(wù)器,一臺運行RootServer/UpdateServer,三臺運行ChunkServer/MergeServer,測試集群系統(tǒng)的機(jī)器配置參數(shù)如表1所示.
表1 硬件配置信息Tab.1 The information of hardware
為了驗證選舉功能模塊和主備切換功能模塊在OceanBase上實現(xiàn)的正確性和效率,可以使用人工模擬RootServer的故障來引發(fā)選舉和集群切換的執(zhí)行,驗證是否能夠選出新的主RootServer出來,并統(tǒng)計從主RootServer宕機(jī)到新的主RootServer被選出并完成主備集群切換流程所用時間.
實驗的步驟如下:
(1)手動殺掉主RootServer的,模擬主RootServer宕機(jī);
(2)記錄新的主RootServer選舉出來并切換集群成功所用時間;
(3)重啟原主RootServer.
(4)每隔5分鐘執(zhí)行步驟1至3,重復(fù)100次.
在三集群和五集群中分別做此實驗,得到的切換耗時如圖8所示.
圖8 主RootSever故障恢復(fù)時間Fig.8 The recovery time of master RootServer
實驗中可以看出在三集群和五集群中選舉并切換的成功率均為100%;三集群中選舉并切換的時長的范圍在15 s~26 s,平均時長為16.7 s,五集群中選舉并切換的時長的范圍在15 s~28 s,平均時長為17.4 s,可見五集群的時長范圍更大一些,并且平均耗時更長一些.這是因為在選舉的過程中跟隨者會隨機(jī)等待1 s~5 s成為候選者,如果兩個跟隨者同時發(fā)起選舉,則會發(fā)生沖突從而重新開始選舉,那么選舉時間就會更長一些.當(dāng)RootServer的個數(shù)越多時,發(fā)生沖突的概率就越大,從而選出主的平均時間就會更長一些.
此實驗是為了驗證日志同步的正確性,在主UpdateServer出現(xiàn)故障宕機(jī)時比較主機(jī)上的最大日志號和所有備機(jī)上的最大日志號以及已提交點,在正確的情況下半數(shù)以上備UpdateServer的最大日志號必然大于等于已提交點.
實驗步驟如下:
(1)使用多線程測試程序?qū)霐?shù)據(jù);
(2)數(shù)據(jù)導(dǎo)入的同時,手動殺死主UpdateServer進(jìn)程,記錄主UpdateServer上的最大日志號和所有備UpdateServer上的最大日志號,以及主UpdateServer上的已提交點,計算已提交點與各UpdateServer上的最大日志號的差值.
(3)重啟原主UpdateServer;
(4)每隔5分鐘執(zhí)行步驟1至3,重復(fù)20次.
在三集群部署模式下測試結(jié)果如圖9所示.
圖9 三集群中測試結(jié)果Fig.9 The test result in 3-clusters
在五集群部署模式下測試結(jié)果如圖10所示.
由圖9和圖10可以看出,每次實驗中,主UpdateServer上的最大日志號都是大于或等于已提交點,所有備UpdateServer上的最大日志號必然有半數(shù)以上與已提交點是相同的.
高可用性是分布式數(shù)據(jù)庫的一個重要性能指標(biāo),本文介紹了傳統(tǒng)數(shù)據(jù)庫的高可用方案和分布式環(huán)境下的幾個高可用一致性算法,在分析了OceanBase系統(tǒng)的可用性方面的缺陷后,對高可用性方案和分布式一致性算法進(jìn)行了一些定制和優(yōu)化,然后介紹了在OceanBase數(shù)據(jù)庫上Raft一致性協(xié)議的實現(xiàn)、集群切換的實現(xiàn)以及日志的同步策略.
圖10 五集群中測試結(jié)果Fig.10 The test result in 5-clusters
當(dāng)前的高可用方案是在多集群模式下實現(xiàn)的,是解決現(xiàn)有問題的最簡潔的解決方案,但是在后續(xù)的設(shè)計中,我們考慮在單集群中也做一些提高可用性的實現(xiàn),從整體上使系統(tǒng)的可用性更高.
[1]陽振坤.OceanBase關(guān)系數(shù)據(jù)庫架構(gòu)[J].華東師范大學(xué)學(xué)報(自然科學(xué)版),2014(5):141-148.
[2]CHANG F,DEAN J,GHEMAWAT S,et al.Bigtable:A distributed storage system for structured data[C]//Proceedings of the 7th Conference on USENIX Symposium on Operating Systems Design and Implementation.2006:205-218.
[3]CORBETT J C,DEAN J,EPSTEIN M,et al.Spanner:Google’s globally-distributed database[C]//Proceedings of the 10th Conference on USENIX Symposium on Operating Systems Design and Implementation.2012:251-264.
[4]DECANDIA G,HASTORUN D,JAMPANI M,et al.Dynamo:Amazon’s highly available key-value store[C]//SOSP′07:205-220.
[5]吳勇毅.工信部力挺軟件國產(chǎn)化 政策機(jī)遇促行業(yè)大發(fā)展[EB/OL].[2014-06-05].http://it.people.com.cn/n/2014/0605/c1009-25108211.html.
[6]OceanBase開源[EB/OL].[2014-06-01].http://code.taobao.org/p/OceanBase/wiki/index/.
[7]楊傳輝.大規(guī)模分布式存儲系統(tǒng):原理解析與架構(gòu)實戰(zhàn)[M].北京:機(jī)械工業(yè)出版社,2013:154-155.
[8]Raft consensus algorithm website[EB/OL].[2014-02-05].https://raftconsensus.github.io.
[9]SKEEN D.A quorum-based commit protocol[C]//Proceedings of the 6th Berkeley Workshop on Distributed Data Management and Computer Networks.1982:69-80.
[10]Oracle maximum availability architecture[EB/OL].[2014-06-01].http://www.oracle.com/technetwork/database/features/availability/maa-096107.html.
[11]Oracle Real Application Clusters[EB/OL].[2014-05-01].http://www.oracle.com/technetwork/cn/database/options/clustering/overview/index.html.
[12]黃劍.基于Oracle Data Guard的容災(zāi)策略設(shè)計與實現(xiàn)[J].科技廣場,2006(11):71-73.
[13]Oracle data guard[EB/OL].[2014-05-06].http://www.oracle.com/technetwork/cn/database/dataguardoverview-091578-zhs.html.
[14]周歡.OceanBase一致性與可用性分析[J].華東師范大學(xué)學(xué)報(自然科學(xué)版),2014(5):103-116.
[15]楊傳輝.OceanBase高可用方案[J].華東師范大學(xué)學(xué)報(自然科學(xué)版),2014(5):173-179.
[16]LAMPORT L.The part-time parliament[J].ACM Transactions on Computer Systems,1998,16(2):133-169.
[17]CHANDRA T D,GRIESEMER R,REDSTONE J.Paxos made live:An engineering perspective[C]//Proceedings of the 26th Annual ACM Symposium on PODC.ACM,2007:398-407.
[18]LAMPORT L,MASSA M.Cheap Paxos[C]//Proceedings of the 2004 International Conference on Dependable Systems and Networks.IEEE,2004:307-314.
[19]LAMPORT L.Fast Paxos[J].Distributed Computing,2006,19(2):79-103.