您好,登錄后才能下訂單哦!
SequoiaDB高可用的原理是什么,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。
1
包括;主備結(jié)構(gòu)和集群架構(gòu);了解到大名鼎鼎的RAFT算法;然后最重要的,巨杉分布式數(shù)據(jù)庫是如何實(shí)一致性的,如何保證在集群環(huán)境中實(shí)現(xiàn)數(shù)據(jù)不錯(cuò)不丟。
2
數(shù)據(jù)庫高可用技術(shù)回顧
數(shù)據(jù)庫系統(tǒng)存儲(chǔ)了一個(gè)IT系統(tǒng)的業(yè)務(wù)數(shù)據(jù),可以說是IT系統(tǒng)的大腦。數(shù)據(jù)庫系統(tǒng)的可用性基本決定了IT系統(tǒng)的可用性,如果數(shù)據(jù)庫系統(tǒng)宕機(jī)那么整個(gè)IT系統(tǒng)就停擺了,甚至如果數(shù)據(jù)庫損壞還可能導(dǎo)致業(yè)務(wù)數(shù)據(jù)丟失,造成極大了經(jīng)濟(jì)損失。
傳統(tǒng)的數(shù)據(jù)庫系統(tǒng),如:Oracle,DB2,SQL Server,MySQL等都是為單機(jī)環(huán)境設(shè)計(jì)的,通常的架構(gòu)是一臺(tái)服務(wù)器加上磁盤陣列的模式。在生產(chǎn)環(huán)境中,就算是采用了可靠性非常高的小型機(jī)及高端磁盤陣列,也難保數(shù)據(jù)庫系統(tǒng)出現(xiàn)服務(wù)器宕機(jī)/掉電/網(wǎng)絡(luò)故障/磁盤陣列故障等問題。就是說,數(shù)據(jù)庫系統(tǒng)在運(yùn)行的過程中出故障是肯定的。那怎么辦呢?經(jīng)過0101訓(xùn)練過的IT“攻城獅”們的大腦也是比較直的。一個(gè)網(wǎng)絡(luò)會(huì)出故障,那么再加一個(gè)網(wǎng)絡(luò);一臺(tái)服務(wù)器會(huì)出問題,那么再加一臺(tái)服務(wù)器;一個(gè)磁盤陣列一份數(shù)據(jù)會(huì)出問題,那么再加一個(gè)磁盤陣列一份數(shù)據(jù)?!肮コ仟{”:“我們的口號(hào)是消除單點(diǎn)故障,保證數(shù)據(jù)庫7*24可用”。PM:“又要加錢!”。
經(jīng)過“攻城獅們”的實(shí)踐,傳統(tǒng)數(shù)據(jù)庫的高可用分為3種架構(gòu):冷備架構(gòu)/熱備架構(gòu)/集群架構(gòu)。
2.1 冷備架構(gòu)
冷備架構(gòu)是主備架構(gòu)的一種,通過增加冗余的網(wǎng)絡(luò)和服務(wù)器,并增加集群管理軟件,如:IBM HACMP,消除網(wǎng)絡(luò)和服務(wù)器單點(diǎn)故障。如圖所示:
主備服務(wù)器上都安裝了數(shù)據(jù)庫軟件和集群管理軟件,并且都能夠通過SAN網(wǎng)絡(luò)訪問磁盤陣列。在正常情況下,主服務(wù)器啟動(dòng)數(shù)據(jù)庫進(jìn)程(備服務(wù)器上并不啟動(dòng)數(shù)據(jù)庫進(jìn)程),并訪問存儲(chǔ)在磁盤陣列中的數(shù)據(jù)庫;集群管理軟件在主備服務(wù)器上都啟動(dòng),監(jiān)控服務(wù)器/網(wǎng)絡(luò)/IO/數(shù)據(jù)庫進(jìn)程狀態(tài)并提供一個(gè)虛擬IP地址(在主服務(wù)器上)供應(yīng)用訪問。
如果集群管理軟件發(fā)現(xiàn)主服務(wù)器不可用(不可用的情況比較多,如掉電/網(wǎng)絡(luò)斷/內(nèi)存CPU故障/無法訪問磁盤陣列/數(shù)據(jù)庫進(jìn)程宕機(jī)等等),就會(huì)啟動(dòng)切換流程。備服務(wù)器:“嘿嘿,終于輪到我上場了,腳都蹲麻了?!?/p>
卸載原來掛載在主服務(wù)器上的磁盤陣列設(shè)備及文件系統(tǒng)。
對(duì)數(shù)據(jù)庫文件系統(tǒng)進(jìn)行檢測(cè)后掛載到備服務(wù)器上。
取消主服務(wù)器上配置的虛擬IP,把虛擬IP配置到備服務(wù)器上。
啟動(dòng)備服務(wù)器上的數(shù)據(jù)庫進(jìn)程;數(shù)據(jù)庫進(jìn)程檢查數(shù)據(jù)庫日志,對(duì)事務(wù)進(jìn)行重新提交或者回滾。
備服務(wù)器數(shù)據(jù)庫正常后開始提供服務(wù),切換完成。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):架構(gòu)和配置簡單,相對(duì)成本較低。
缺點(diǎn):需要重新掛載文件系統(tǒng),啟動(dòng)數(shù)據(jù)庫進(jìn)程,數(shù)據(jù)庫日志檢查,切換時(shí)間以分鐘計(jì),如果需要回滾的事務(wù)太多,可能是幾十分鐘,對(duì)可用性要求比較高的業(yè)務(wù)無法忍受;備服務(wù)器冷備浪費(fèi)一臺(tái)服務(wù)器資源;磁盤陣列只有一個(gè)是單點(diǎn);數(shù)據(jù)只有一份是單點(diǎn)。
2.2 熱備架構(gòu)
熱備架構(gòu)是主備架構(gòu)的另外一種,在冷備架構(gòu)中加入了另外一臺(tái)磁盤陣列存儲(chǔ)多一份的數(shù)據(jù)庫數(shù)據(jù),并且備服務(wù)器的數(shù)據(jù)庫進(jìn)程是啟動(dòng)的持續(xù)的對(duì)主服務(wù)器發(fā)送的日志進(jìn)行重用。熱備架構(gòu)的實(shí)現(xiàn)包括:IBM DB2 HADR,Oracle DataGurd,MySQL Binglog Replication等。
如圖所示:
正常情況下,業(yè)務(wù)應(yīng)用通過虛擬IP訪問主服務(wù)器,主服務(wù)器訪問自己磁盤陣列中的主數(shù)據(jù)庫;主服務(wù)器數(shù)據(jù)庫進(jìn)程啟動(dòng)日志復(fù)制功能,把事務(wù)日志復(fù)制到備服務(wù)器的數(shù)據(jù)庫進(jìn)程;備服務(wù)器的數(shù)據(jù)庫進(jìn)程把日志重用到備數(shù)據(jù)庫中,完成數(shù)據(jù)同步。
如果主服務(wù)器不可用,集群管理軟件會(huì)啟動(dòng)切換流程。
集群管理軟件取消主服務(wù)器的虛擬IP配置,并把虛擬IP配置到備服務(wù)器。
被服務(wù)器的數(shù)據(jù)庫進(jìn)程執(zhí)行切換操作,從備升級(jí)到主。
備服務(wù)器的數(shù)據(jù)庫進(jìn)程完成日志重用后,可用開始提供服務(wù)。
優(yōu)點(diǎn):由于備服務(wù)器的數(shù)據(jù)庫進(jìn)程是啟動(dòng)狀態(tài),并且事務(wù)日志持續(xù)重用,切換時(shí)間短(秒級(jí)別);數(shù)據(jù)是兩份,排除了磁盤陣列和數(shù)據(jù)的單點(diǎn);備服務(wù)器一般不能寫但是可以提供讀服務(wù)。缺點(diǎn):增加了一套磁盤陣列,增加了成本。
2.3 集群架構(gòu)
前面兩種架構(gòu)解決了高可用問題,但是數(shù)據(jù)庫系統(tǒng)都只能進(jìn)行縱向擴(kuò)展(增加單個(gè)服務(wù)器的CPU,內(nèi)存),不能進(jìn)行橫向擴(kuò)展(增加服務(wù)器)的方式實(shí)現(xiàn)性能擴(kuò)充。
客戶:”我要橫向擴(kuò)展“。
攻城獅:”我好難啊,但是可以有“。
通過在數(shù)據(jù)庫系統(tǒng)中提供共享存儲(chǔ)的能力,如:IBM DB2 pureScale,Oracle RAC,多臺(tái)服務(wù)器上的數(shù)據(jù)庫進(jìn)程能夠并行訪問一個(gè)共享存儲(chǔ)上的數(shù)據(jù)庫數(shù)據(jù)。
如圖所示:
正常情況下,業(yè)務(wù)應(yīng)用可以連接到任意一臺(tái)數(shù)據(jù)庫服務(wù)器上執(zhí)行數(shù)據(jù)庫讀寫操作;數(shù)據(jù)庫進(jìn)程通過并行訪問控制實(shí)現(xiàn)對(duì)共享磁盤陣列中的數(shù)據(jù)庫的并行讀寫。
如果一臺(tái)服務(wù)器不可用,那么連接到這臺(tái)服務(wù)器上的應(yīng)用會(huì)自動(dòng)重新連接到另外的數(shù)據(jù)庫服務(wù)器上,實(shí)現(xiàn)高可用性。
優(yōu)點(diǎn):
切換時(shí)間短(秒級(jí));可以實(shí)現(xiàn)橫向擴(kuò)展;具有負(fù)載均衡能力;
缺點(diǎn):
橫向擴(kuò)展能力有限,一般2臺(tái)服務(wù)器的案例居多,3臺(tái)服務(wù)器以上的案例很少,服務(wù)器太多性能會(huì)不增反降;成本較高;配置管理復(fù)雜,DBA需要非常高的數(shù)據(jù)庫管理能力。
3
巨杉分布式數(shù)據(jù)庫的高可用技術(shù)
小伙伴們可能要問:”傳統(tǒng)數(shù)據(jù)庫已經(jīng)實(shí)現(xiàn)了高可用和橫向擴(kuò)展,為啥要用分布式數(shù)據(jù)庫呢?“
攻城獅:”答。首先,傳統(tǒng)數(shù)據(jù)庫橫向擴(kuò)展能力有限一般2-3臺(tái)服務(wù)器,無法應(yīng)對(duì)現(xiàn)在的大數(shù)據(jù)場景;其次,貴啊?;◣装偃f用2臺(tái)小型機(jī)加高端磁盤陣列加ORACLE RAC搭建一個(gè)核心數(shù)據(jù)庫,為了穩(wěn)定性也就罷了,但是需要處理幾百TB數(shù)據(jù),需要幾十上百臺(tái)服務(wù)器的數(shù)據(jù)庫系統(tǒng)怎么搞?“
巨杉數(shù)據(jù)庫:”該我登場了。不需要磁盤整理,不需要SAN網(wǎng)絡(luò),使用PC服務(wù)器加內(nèi)置磁盤加分布式數(shù)據(jù)庫軟件,實(shí)現(xiàn)低成本/高可用性/高可擴(kuò)展性/高性能的數(shù)據(jù)庫系統(tǒng)。歐耶!“
由于采用了PC服務(wù)器加內(nèi)置磁盤的方式,數(shù)據(jù)一致性和高可用是分布式數(shù)據(jù)庫設(shè)計(jì)里面最重要的一環(huán)。這里我們將討論巨杉數(shù)據(jù)庫的高可用實(shí)現(xiàn)技術(shù)。巨杉數(shù)據(jù)庫的高可用技術(shù)原理與RAFT算法類似,借鑒了RAFT選舉算法進(jìn)行了優(yōu)化,以便能夠更好的支持分布式數(shù)據(jù)庫的場景。
3.1 Raft算法
RAFT是一種為了管理復(fù)制日志的一致性的算法。那么RAFT算法是怎么來的了。在RAFT算法出現(xiàn)之前,Paxos算法統(tǒng)治著一致性算法鄰域,但是Paxos的顯著缺點(diǎn)是”十分難于理解“,當(dāng)然也就難于實(shí)現(xiàn)。2013年,斯坦福的Diego Ongaro和John Ousterhout以易于理解為目標(biāo)設(shè)計(jì)了RAFT一致性算法,并發(fā)表論文《In Search of an Understandable Consensus Algorithm》。RAFT算法的易于理解和易于實(shí)現(xiàn)使得其在業(yè)界得到了廣泛的應(yīng)用,并在這些實(shí)踐中證明了算法的正確性。給大佬們點(diǎn)贊,大佬們的想法是”這個(gè)世界給不了我想要的,那我就改變這個(gè)世界“。
這里將簡單介紹一下RAFT算法的原理,以幫助大家理解巨杉分布式數(shù)據(jù)庫的高可用性。如果想詳細(xì)的了解RAFT算法可以參考github上的文章:
https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md
RAFT算法的設(shè)計(jì)思路就是復(fù)雜問題簡單化,把一組服務(wù)器的數(shù)據(jù)一致性問題分解為3個(gè)小問題。這3小問題包括:
領(lǐng)導(dǎo)選舉:當(dāng)現(xiàn)存的領(lǐng)導(dǎo)人宕機(jī)的時(shí)候,一個(gè)新的領(lǐng)導(dǎo)人需要被選舉出來
日志復(fù)制:領(lǐng)導(dǎo)人必須從客戶端接收日志然后復(fù)制到集群中的其他節(jié)點(diǎn),并且強(qiáng)制要求其他節(jié)點(diǎn)的日志保持和自己相同。
安全性:在 Raft 中安全性的關(guān)鍵是狀態(tài)機(jī)安全:如果有任何的服務(wù)器節(jié)點(diǎn)已經(jīng)應(yīng)用了一個(gè)確定的日志條目到它的狀態(tài)機(jī)中,那么其他服務(wù)器節(jié)點(diǎn)不能在同一個(gè)日志索引位置應(yīng)用一個(gè)不同的指令。
通過解決上面的3個(gè)小問題來,Raft解決了一致性這個(gè)大問題。
Raft算法還簡化了復(fù)制狀態(tài)機(jī)的數(shù)量,每臺(tái)服務(wù)器一定會(huì)處于三種狀態(tài):領(lǐng)導(dǎo)人(Leader),候選人(Candidate),追隨者(Follower)。狀態(tài)的轉(zhuǎn)換如圖所示:
追隨者只響應(yīng)其他服務(wù)器的請(qǐng)求。如果追隨者沒有收到任何消息,它會(huì)成為一個(gè)候選人并且開始一次選舉。收到大多數(shù)服務(wù)器投票的候選人會(huì)成為新的領(lǐng)導(dǎo)人。領(lǐng)導(dǎo)人在它們宕機(jī)之前會(huì)一直保持領(lǐng)導(dǎo)人的狀態(tài)。
3.1.1 領(lǐng)導(dǎo)者選舉
RAFT算法建議一組服務(wù)器至少包括5臺(tái)服務(wù)器,這樣在有2臺(tái)服務(wù)器宕機(jī)的情況下,集群任然能夠提供服務(wù)。服務(wù)器的狀態(tài)只能是3中狀態(tài)中的一種,并且在一個(gè)集群里只能有一個(gè)領(lǐng)導(dǎo)人。集群服務(wù)器之間通過心跳信息相互了解狀態(tài)情況并觸發(fā)選舉。當(dāng)服務(wù)器程序啟動(dòng)時(shí),他們都是跟隨者身份。一個(gè)服務(wù)器節(jié)點(diǎn)繼續(xù)保持著跟隨者狀態(tài)只要他從領(lǐng)導(dǎo)人或者候選者處接收到有效的 RPCs。領(lǐng)導(dǎo)者周期性的向所有跟隨者發(fā)送心跳包(即不包含日志項(xiàng)內(nèi)容的附加日志項(xiàng) RPCs)來維持自己的權(quán)威。如果一個(gè)跟隨者在一段時(shí)間里沒有接收到任何消息,也就是選舉超時(shí),那么他就會(huì)認(rèn)為系統(tǒng)中沒有可用的領(lǐng)導(dǎo)者,并且發(fā)起選舉以選出新的領(lǐng)導(dǎo)者。
要開始一次選舉過程,跟隨者先要增加自己的當(dāng)前任期號(hào)并且轉(zhuǎn)換到候選人狀態(tài)。然后他會(huì)并行的向集群中的其他服務(wù)器節(jié)點(diǎn)發(fā)送請(qǐng)求投票的 RPCs 來給自己投票。候選人會(huì)繼續(xù)保持著當(dāng)前狀態(tài)直到以下三件事情之一發(fā)生:(a) 他自己贏得了這次的選舉,(b) 其他的服務(wù)器成為領(lǐng)導(dǎo)者,(c) 一段時(shí)間之后沒有任何一個(gè)獲勝的人。候選人必須獲得集群中的一半服務(wù)器以上的投票才能成為領(lǐng)導(dǎo)人。
3.1.2 日志復(fù)制
一旦一個(gè)領(lǐng)導(dǎo)人被選舉出來,他就開始為客戶端提供服務(wù)??蛻舳说拿恳粋€(gè)請(qǐng)求都包含一條被復(fù)制狀態(tài)機(jī)執(zhí)行的指令。領(lǐng)導(dǎo)人把這條指令作為一條新的日志條目附加到日志中去,然后并行的發(fā)起附加條目 RPCs 給其他的服務(wù)器,讓他們復(fù)制這條日志條目。當(dāng)這條日志條目被安全的復(fù)制(下面會(huì)介紹),領(lǐng)導(dǎo)人會(huì)應(yīng)用這條日志條目到它的狀態(tài)機(jī)中然后把執(zhí)行的結(jié)果返回給客戶端。如果跟隨者崩潰或者運(yùn)行緩慢,再或者網(wǎng)絡(luò)丟包,領(lǐng)導(dǎo)人會(huì)不斷的重復(fù)嘗試附加日志條目 RPCs (盡管已經(jīng)回復(fù)了客戶端)直到所有的跟隨者都最終存儲(chǔ)了所有的日志條目。
領(lǐng)導(dǎo)人來決定什么時(shí)候把日志條目應(yīng)用到狀態(tài)機(jī)中是安全的;這種日志條目被稱為已提交。Raft 算法保證所有已提交的日志條目都是持久化的并且最終會(huì)被所有可用的狀態(tài)機(jī)執(zhí)行。在領(lǐng)導(dǎo)人將創(chuàng)建的日志條目復(fù)制到大多數(shù)的服務(wù)器上的時(shí)候,日志條目就會(huì)被提交。同時(shí),領(lǐng)導(dǎo)人的日志中之前的所有日志條目也都會(huì)被提交,包括由其他領(lǐng)導(dǎo)人創(chuàng)建的條目。領(lǐng)導(dǎo)人跟蹤了最大的將會(huì)被提交的日志項(xiàng)的索引,并且索引值會(huì)被包含在未來的所有附加日志 RPCs (包括心跳包),這樣其他的服務(wù)器才能最終知道領(lǐng)導(dǎo)人的提交位置。一旦跟隨者知道一條日志條目已經(jīng)被提交,那么他也會(huì)將這個(gè)日志條目應(yīng)用到本地的狀態(tài)機(jī)中(按照日志的順序)。
日志復(fù)制機(jī)制展示出了一致性特性:Raft 能夠接受,復(fù)制并應(yīng)用新的日志條目只要大部分的機(jī)器是工作的;在通常的情況下,新的日志條目可以在一次 RPC 中被復(fù)制給集群中的大多數(shù)機(jī)器;并且單個(gè)的緩慢的跟隨者不會(huì)影響整體的性能。
3.1.3 安全性
然而,到目前為止描述的機(jī)制并不能充分的保證每一個(gè)狀態(tài)機(jī)會(huì)按照相同的順序執(zhí)行相同的指令。例如,一個(gè)跟隨者可能會(huì)進(jìn)入不可用狀態(tài)同時(shí)領(lǐng)導(dǎo)人已經(jīng)提交了若干的日志條目,然后這個(gè)跟隨者可能會(huì)被選舉為領(lǐng)導(dǎo)人并且覆蓋這些日志條目;因此,不同的狀態(tài)機(jī)可能會(huì)執(zhí)行不同的指令序列。
這一節(jié)通過在領(lǐng)導(dǎo)選舉的時(shí)候增加一些限制來完善 Raft 算法。這一限制保證了任何的領(lǐng)導(dǎo)人對(duì)于給定的任期號(hào),都擁有了之前任期的所有被提交的日志條目。增加這一選舉時(shí)的限制,我們對(duì)于提交時(shí)的規(guī)則也更加清晰。最終,我們將展示對(duì)于領(lǐng)導(dǎo)人完整特性的簡要證明,并且說明領(lǐng)導(dǎo)人完整性特性是如何引導(dǎo)復(fù)制狀態(tài)機(jī)做出正確行為的。
選舉安全性
Raft 使用了一種更加簡單的方法,它可以保證所有之前的任期號(hào)中已經(jīng)提交的日志條目在選舉的時(shí)候都會(huì)出現(xiàn)在新的領(lǐng)導(dǎo)人中,不需要傳送這些日志條目給領(lǐng)導(dǎo)人。這意味著日志條目的傳送是單向的,只從領(lǐng)導(dǎo)人傳給跟隨者,并且領(lǐng)導(dǎo)人從不會(huì)覆蓋自身本地日志中已經(jīng)存在的條目。
Raft 使用投票的方式來阻止一個(gè)候選人贏得選舉除非這個(gè)候選人包含了所有已經(jīng)提交的日志條目。候選人為了贏得選舉必須聯(lián)系集群中的大部分節(jié)點(diǎn),這意味著每一個(gè)已經(jīng)提交的日志條目在這些服務(wù)器節(jié)點(diǎn)中肯定存在于至少一個(gè)節(jié)點(diǎn)上。如果候選人的日志至少和大多數(shù)的服務(wù)器節(jié)點(diǎn)一樣新(這個(gè)新的定義會(huì)在下面討論),那么他一定持有了所有已經(jīng)提交的日志條目。請(qǐng)求投票 RPC 實(shí)現(xiàn)了這樣的限制:RPC 中包含了候選人的日志信息,然后投票人會(huì)拒絕掉那些日志沒有自己新的投票請(qǐng)求。
Raft 通過比較兩份日志中最后一條日志條目的索引值和任期號(hào)定義誰的日志比較新。如果兩份日志最后的條目的任期號(hào)不同,那么任期號(hào)大的日志更加新。如果兩份日志最后的條目任期號(hào)相同,那么日志比較長的那個(gè)就更加新。
提交之前任期內(nèi)的日志條目
RAFT中領(lǐng)導(dǎo)人知道一條當(dāng)前任期內(nèi)的日志記錄是可以被提交的,只要它被存儲(chǔ)到了大多數(shù)的服務(wù)器上。如果一個(gè)領(lǐng)導(dǎo)人在提交日志條目之前崩潰了,未來后續(xù)的領(lǐng)導(dǎo)人會(huì)繼續(xù)嘗試復(fù)制這條日志記錄。RAFT的領(lǐng)導(dǎo)人選舉機(jī)制保證了新領(lǐng)導(dǎo)人的日志中必然包含了前一個(gè)任期的已經(jīng)復(fù)制到大多數(shù)服務(wù)器的最新的任期號(hào)和最新的日志條目,這樣新領(lǐng)導(dǎo)人就可以通過日志匹配特性,把之前任期的日志條目復(fù)制到其它服務(wù)器上,實(shí)現(xiàn)間接提交。
3.2 巨杉數(shù)據(jù)庫的高可用實(shí)現(xiàn)
由于分布式數(shù)據(jù)庫必須具有數(shù)據(jù)庫的ACID(原子性,一致性,隔離性,持久性)及分布式事務(wù)能力,并且還需要提供高性能的并行計(jì)算能力,其場景遠(yuǎn)比RAFT算法中提到的復(fù)雜的多。
例如:RAFT算法通過保證日志的順序來保證各個(gè)節(jié)點(diǎn)數(shù)據(jù)的一致性,但是在數(shù)據(jù)庫的事務(wù)并行執(zhí)行過程中,每個(gè)事務(wù)都可能產(chǎn)生多個(gè)日志記錄,多個(gè)事務(wù)的日志記錄很可能是交叉產(chǎn)生的而不是順序的,要在分布式環(huán)境中保持事務(wù)的原子性,就要求一個(gè)事務(wù)產(chǎn)生的所有日志記錄是可追蹤的,在每個(gè)節(jié)點(diǎn)上這些日志都必須存在,這樣在事務(wù)提交或者回滾的時(shí)候才能夠在每個(gè)節(jié)點(diǎn)上保持原子性。在事務(wù)執(zhí)行過程中,有可能會(huì)更新大量數(shù)據(jù)(批處理事務(wù)),這些更新操作在分布式數(shù)據(jù)庫中不可能采用等到主節(jié)點(diǎn)執(zhí)行完成,然后再復(fù)制到從節(jié)點(diǎn)的方法,這種方法的執(zhí)行性能太差,無法滿足業(yè)務(wù)需求。巨杉數(shù)據(jù)庫的做法是事務(wù)中的每個(gè)寫操作都會(huì)產(chǎn)生一個(gè)日志記錄,主節(jié)點(diǎn)會(huì)把這些日志記錄復(fù)制到從節(jié)點(diǎn)重做,并不會(huì)等到事務(wù)提交才開始復(fù)制重做,然后在事務(wù)提交的時(shí)候,在復(fù)制組內(nèi)部實(shí)現(xiàn)二階段提交算法,保證事務(wù)在復(fù)制組中的原子性和一致性。
另外,RAFT算法中的命令提交成功條件是:集群中的大部分服務(wù)器持有了這條命令的日志記錄。RAFT算法能保證集群是最終一致的,但不保證某個(gè)時(shí)刻集群是一致的。這種機(jī)制在實(shí)現(xiàn)集群災(zāi)備的時(shí)候會(huì)有問題。例如:在5臺(tái)服務(wù)器的集群中,3臺(tái)在中心A,2臺(tái)在中心B,如果領(lǐng)導(dǎo)人在中心A中,那么A中的3臺(tái)服務(wù)器處于同一個(gè)網(wǎng)絡(luò),通常情況下日志復(fù)制時(shí)間都要比處于遠(yuǎn)端中心B的2臺(tái)服務(wù)器短,也就是說不能保證中心B的服務(wù)器中必定持有最新的日志記錄,如果中心A出現(xiàn)災(zāi)難事故,無法恢復(fù),那么中心B中的服務(wù)器的數(shù)據(jù)是不完整的。這中情況對(duì)于某些業(yè)務(wù)(銀行賬務(wù))是無法接受的。巨杉數(shù)據(jù)庫的做法是設(shè)置寫副本數(shù)參數(shù),強(qiáng)制要求必須有多少個(gè)節(jié)點(diǎn)都持有最新日志記錄,才算是復(fù)制成功。
所以,巨杉分布式數(shù)據(jù)庫在節(jié)點(diǎn)選舉的實(shí)現(xiàn)中優(yōu)化了RAFT算法,而在數(shù)據(jù)同步/日志復(fù)制則完全開發(fā)了自己的算法。在巨杉分布式數(shù)據(jù)庫的架構(gòu)中,主節(jié)點(diǎn)對(duì)應(yīng)了RAFT算法中的領(lǐng)導(dǎo)人,從節(jié)點(diǎn)對(duì)應(yīng)跟隨人,候選人是一樣的;巨杉數(shù)據(jù)庫的復(fù)制日志對(duì)應(yīng)了RAFT算法中的日志記錄;巨杉數(shù)據(jù)庫的復(fù)制組對(duì)應(yīng)了一個(gè)RAFT算法中的一組服務(wù)器。巨杉數(shù)據(jù)庫在一個(gè)集群里面支持多個(gè)復(fù)制組,每個(gè)復(fù)制組都可以看作是一組RAFT算法的服務(wù)器。
巨杉分布式數(shù)據(jù)庫的節(jié)點(diǎn)類型分為:協(xié)調(diào)節(jié)點(diǎn),編目節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn)。其中,多個(gè)協(xié)調(diào)節(jié)點(diǎn)的任務(wù)是接收命令,并分發(fā)命令到編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn),本身不保存數(shù)據(jù),相互之間也沒有關(guān)系,所以不需要考慮可用性問題。編目節(jié)點(diǎn)其實(shí)就是一種特殊的數(shù)據(jù)節(jié)點(diǎn),其高可用性是和數(shù)據(jù)節(jié)點(diǎn)一樣的。協(xié)調(diào)節(jié)點(diǎn)可以看作是數(shù)據(jù)節(jié)點(diǎn)復(fù)制組的客戶端。
巨杉分布式數(shù)據(jù)庫也是通過解決3個(gè)小問題,從而實(shí)現(xiàn)了集群數(shù)據(jù)一致性這個(gè)大問題的。
3.2.1 節(jié)點(diǎn)選舉
巨杉數(shù)據(jù)庫的復(fù)制組可以包含1個(gè)到7個(gè)數(shù)據(jù)節(jié)點(diǎn),但是如果要提供高可用特性復(fù)制組的節(jié)點(diǎn)數(shù)量必須大于等于3。每個(gè)復(fù)制組在同一時(shí)間只會(huì)有一個(gè)主節(jié)點(diǎn),其它的都是從節(jié)點(diǎn),如果處于選主階段,每個(gè)從節(jié)點(diǎn)都可以是候選節(jié)點(diǎn)。巨杉數(shù)據(jù)庫選主也是采用同組節(jié)點(diǎn)投票的方式,獲得半數(shù)以上選票的節(jié)點(diǎn)成為主節(jié)點(diǎn)。
為了保證選主成功并且選出的主節(jié)點(diǎn)包含了最新的數(shù)據(jù)庫日志,巨杉數(shù)據(jù)庫在RAFT算法的基礎(chǔ)上做了一些優(yōu)化,特別是在候選節(jié)點(diǎn)的資格選擇上。
從節(jié)點(diǎn)要成為候選節(jié)點(diǎn)并發(fā)起選舉請(qǐng)求必須具有的條件是:自己不是主節(jié)點(diǎn),剩下能與自己心跳通訊的節(jié)點(diǎn)數(shù)量必須大于半數(shù)以上,自己的LSN(日志序列號(hào))比其它節(jié)點(diǎn)的LSN新。復(fù)制組在主節(jié)點(diǎn)存在的情況下不能自動(dòng)發(fā)起選舉請(qǐng)求(可以采用手工發(fā)起的方式切換主節(jié)點(diǎn)),只有當(dāng)主節(jié)點(diǎn)不可用的情況下,從節(jié)點(diǎn)才可以發(fā)起選主請(qǐng)求。如果是集群分裂的情況,比如5個(gè)節(jié)點(diǎn)由于網(wǎng)絡(luò)原因分裂為相互不通的2節(jié)點(diǎn)集群和3節(jié)點(diǎn)集群,如果當(dāng)前主節(jié)點(diǎn)在3節(jié)點(diǎn)的集群中,那么由于此集群的節(jié)點(diǎn)存活數(shù)大于半數(shù),不會(huì)發(fā)生選主,如果當(dāng)前主節(jié)點(diǎn)在2節(jié)點(diǎn)的集群中,那么主節(jié)點(diǎn)將自動(dòng)降為從節(jié)點(diǎn),并且3節(jié)點(diǎn)的集群將發(fā)起選主請(qǐng)求,重新選擇一個(gè)主節(jié)點(diǎn)。
在復(fù)制組所有節(jié)點(diǎn)正常的時(shí)候,每個(gè)節(jié)點(diǎn)都會(huì)通過共享心跳信息sharing-beat共享狀態(tài)信息。共享心跳信息包括:心跳 ID、自身開始LSN、自身終止LSN、時(shí)間戳、數(shù)據(jù)組版本號(hào)、自身當(dāng)前的角色和同步狀態(tài)。如圖所示:
每個(gè)節(jié)點(diǎn)都維護(hù)一張 status-sharing table 表,用來記錄節(jié)點(diǎn)狀態(tài)。sharing-beat 每2秒發(fā)送一次,采集應(yīng)答信息,若連續(xù)兩次未收到應(yīng)答信息,則認(rèn)為節(jié)點(diǎn)宕機(jī)。節(jié)點(diǎn)進(jìn)程中的ReplReader(復(fù)制監(jiān)聽線程)負(fù)責(zé)節(jié)點(diǎn)狀態(tài)信息的接收和發(fā)送。
從節(jié)點(diǎn)發(fā)起選主之前,會(huì)檢查共享心跳信息中本節(jié)點(diǎn)的LSN以及其它從節(jié)點(diǎn)的LSN,如果自己LSN大于等于其它從節(jié)點(diǎn)的LSN,就可以發(fā)起選主請(qǐng)求,否則就不發(fā)起。
在選主中,如果多個(gè)候選從節(jié)點(diǎn)的LSN相同,并且都發(fā)起了請(qǐng)求,那么將比較各從節(jié)點(diǎn)的權(quán)重配置參數(shù)(weight)。復(fù)制組的每個(gè)節(jié)點(diǎn)都可單獨(dú)配置不同的權(quán)重,從0到100,數(shù)字越大權(quán)重越高,相同LSN的從節(jié)點(diǎn),權(quán)重高的選主成功。
如果多個(gè)從節(jié)點(diǎn)的LSN相同,權(quán)重配置也相同,那么將比較這些從節(jié)點(diǎn)的節(jié)點(diǎn)號(hào),在創(chuàng)建節(jié)點(diǎn)的時(shí)候,每個(gè)節(jié)點(diǎn)的節(jié)點(diǎn)號(hào)是不同的,節(jié)點(diǎn)號(hào)大的將選主成功。
從上面可以看出巨杉分布式數(shù)據(jù)庫在選主中,優(yōu)化了選主流程,在RAFT算法的基礎(chǔ)上增加了權(quán)重和節(jié)點(diǎn)號(hào)的判斷,這樣就不會(huì)出現(xiàn)RAFT算法中多個(gè)節(jié)點(diǎn)選主票數(shù)相同導(dǎo)致失敗的情況。
下面舉一個(gè)簡單例子,描述一下巨杉數(shù)據(jù)庫的選主流程。
如圖所示,一個(gè)3節(jié)點(diǎn)的復(fù)制組,包括:主節(jié)點(diǎn)A,從節(jié)點(diǎn)B,從節(jié)點(diǎn)C。在正常情況下,三個(gè)節(jié)點(diǎn)通過心跳共享狀態(tài)信息。如果主節(jié)點(diǎn)A由于某種原因故障(服務(wù)器掉電/網(wǎng)絡(luò)故障/磁盤故障等等)將自動(dòng)降為從節(jié)點(diǎn),集群開始重新選主。
兩個(gè)從節(jié)點(diǎn),發(fā)現(xiàn)2輪沒有收到主節(jié)點(diǎn)的心跳信息,則認(rèn)為主節(jié)點(diǎn)宕機(jī)。
從節(jié)點(diǎn)B:”嘿嘿,主節(jié)點(diǎn)掛了,我有機(jī)會(huì)當(dāng)老大了。我看看,我是從節(jié)點(diǎn),LSN是最新的。嗨,C兄,我的LSN是XXX,我要當(dāng)老大,你同意嗎?“
從節(jié)點(diǎn)C:”嘎嘎,老大掛了!不當(dāng)大哥很多年,有點(diǎn)想念。我看看,我是從節(jié)點(diǎn),LSN是最新的,有機(jī)會(huì)。嗨,B兄,我的LSN是XXX,我要當(dāng)老大,你同意嗎?“
從節(jié)點(diǎn)B:”C兄也想當(dāng)老大,LSN和我一樣。嗨C兄,我的LSN也是XXX,我的權(quán)重是80,還是我當(dāng)?”
從節(jié)點(diǎn)C:“B兄不好意思,我的權(quán)重也是80,我也想當(dāng)。我的節(jié)點(diǎn)號(hào)是1008?!?/p>
從節(jié)點(diǎn)B:“C兄的節(jié)點(diǎn)號(hào)是1008,我的是1006;輸了輸了,C兄你是老大了?!?/p>
從節(jié)點(diǎn)C:“我自己投了自己一票,B兄投了我一篇,現(xiàn)在是2票,大于3/2+1,嗯夠了。嗨B兄我是老大了?!?/p>
從節(jié)點(diǎn)B:“收到,老大?!?/p>
重新選主成功后,新主節(jié)點(diǎn)會(huì)通知編目節(jié)點(diǎn)變更主節(jié)點(diǎn)信息;協(xié)調(diào)節(jié)點(diǎn)會(huì)從編目節(jié)點(diǎn)同步節(jié)點(diǎn)狀態(tài)信息,并連接到新主節(jié)點(diǎn);協(xié)調(diào)節(jié)點(diǎn)也可以通過遍歷節(jié)點(diǎn)的方式來獲得新主節(jié)點(diǎn)信息。這樣就在主節(jié)點(diǎn)宕機(jī)后實(shí)現(xiàn)了高可用能力。原主節(jié)點(diǎn)A恢復(fù)后,自動(dòng)成為從節(jié)點(diǎn)。
3.2.2 日志復(fù)制
巨杉數(shù)據(jù)庫的日志復(fù)制機(jī)制與RAFT的日志復(fù)制機(jī)制不同。首先,RAFT算法的日志總是從領(lǐng)導(dǎo)人(Leader)發(fā)送給追隨者(Follower),追隨者之間不會(huì)交換日志數(shù)據(jù);而巨杉數(shù)據(jù)庫的日志復(fù)制在源節(jié)點(diǎn)(發(fā)送日志的節(jié)點(diǎn))和目標(biāo)節(jié)點(diǎn)(請(qǐng)求日志的節(jié)點(diǎn))之間進(jìn)行,并且是目標(biāo)節(jié)點(diǎn)主動(dòng)向源節(jié)點(diǎn)請(qǐng)求日志數(shù)據(jù),源節(jié)點(diǎn)大多數(shù)情況是主節(jié)點(diǎn),但其它從節(jié)點(diǎn)也可以是源節(jié)點(diǎn),目標(biāo)節(jié)點(diǎn)只能是從節(jié)點(diǎn)。其次,RAFT算法中如果領(lǐng)導(dǎo)人沒有追隨者的日志復(fù)制返回信息,領(lǐng)導(dǎo)人會(huì)持續(xù)的給這個(gè)追隨者發(fā)送日志直到收到返回信息,都是增量復(fù)制;而巨杉數(shù)據(jù)庫的數(shù)據(jù)同步復(fù)制可以是日志增量復(fù)制,也可能觸發(fā)數(shù)據(jù)全量同步。
巨杉數(shù)據(jù)庫的日志復(fù)制不采用RAFT算法是因?yàn)槠湓诜植际綌?shù)據(jù)庫的場景中并不適合。例如,如果某個(gè)從節(jié)點(diǎn)宕機(jī),而按照RAFT算法主節(jié)點(diǎn)持續(xù)的向此從節(jié)點(diǎn)發(fā)送日志信息,而日志數(shù)據(jù)又很大,那么就會(huì)占用主節(jié)點(diǎn)大量的CPU/內(nèi)存/網(wǎng)絡(luò)資源,嚴(yán)重的影響主節(jié)點(diǎn)的性能,有可能造成阻塞;巨杉數(shù)據(jù)庫采用從節(jié)點(diǎn)請(qǐng)求的方式,只有從節(jié)點(diǎn)是正常狀態(tài)的時(shí)候才會(huì)請(qǐng)求新的日志數(shù)據(jù),并清楚的給出需要哪些日志數(shù)據(jù),不會(huì)造成重復(fù)發(fā)送問題,并且從節(jié)點(diǎn)可以作為源節(jié)點(diǎn)以可以大大減少主節(jié)點(diǎn)的工作負(fù)載。另外,由于實(shí)際環(huán)境中,存儲(chǔ)空間是有限的,數(shù)據(jù)庫能夠配置的日志空間也是有限的,所以巨杉數(shù)據(jù)庫的數(shù)據(jù)同步模式分為日志增量同步和數(shù)據(jù)全量同步兩種方式。如果目標(biāo)節(jié)點(diǎn)需要同步的數(shù)據(jù)都包含在源節(jié)點(diǎn)的復(fù)制日志空間中,就進(jìn)行日志增量同步;如果數(shù)據(jù)已經(jīng)不在復(fù)制日志空間中,那么需要進(jìn)行全量同步。最重要的是,分布式數(shù)據(jù)庫要求支持ACID及事務(wù)的能力,其場景比RAFT算法描述的日志復(fù)制場景更復(fù)雜,巨杉數(shù)據(jù)庫采用兩階段提交的算法在兼顧性能和事務(wù)一致性的情況下支持復(fù)制組內(nèi)部的事務(wù)能力。
日志增量同步模式
在數(shù)據(jù)節(jié)點(diǎn)和編目節(jié)點(diǎn)中,任何數(shù)據(jù)增刪改操作均會(huì)寫入日志。SequoiaDB 會(huì)首先將日志寫入日志緩沖區(qū),然后將其異步寫入本地磁盤。
每個(gè)數(shù)據(jù)復(fù)制會(huì)在兩個(gè)節(jié)點(diǎn)間進(jìn)行:
源節(jié)點(diǎn): 為包含新數(shù)據(jù)的節(jié)點(diǎn)。主節(jié)點(diǎn)并不一定永遠(yuǎn)是復(fù)制的源節(jié)點(diǎn)。
目標(biāo)節(jié)點(diǎn): 為請(qǐng)求進(jìn)行數(shù)據(jù)復(fù)制的節(jié)點(diǎn)。
復(fù)制過程中,目標(biāo)節(jié)點(diǎn)選擇一個(gè)與其最接近的節(jié)點(diǎn)(在共享的節(jié)點(diǎn)狀態(tài)表中,包含了每個(gè)節(jié)點(diǎn)的開始LSN和結(jié)束LSN可用計(jì)算哪個(gè)與自己最接近),然后向其發(fā)送一個(gè)復(fù)制請(qǐng)求。源節(jié)點(diǎn)接到復(fù)制請(qǐng)求后,會(huì)將目標(biāo)節(jié)點(diǎn)請(qǐng)求的同步點(diǎn)之后的日志記錄打包并發(fā)送給目標(biāo)節(jié)點(diǎn),目標(biāo)節(jié)點(diǎn)接收到數(shù)據(jù)包后會(huì)重新處理日志中的所有操作。
節(jié)點(diǎn)之間的復(fù)制有兩個(gè)狀態(tài):
對(duì)等狀態(tài)(PEER):當(dāng)目標(biāo)節(jié)點(diǎn)請(qǐng)求的日志依然存在于源節(jié)點(diǎn)的日志緩沖區(qū)中,兩節(jié)點(diǎn)之間為對(duì)等狀態(tài)
遠(yuǎn)程追趕狀態(tài)(RemoteCatchup):當(dāng)目標(biāo)節(jié)點(diǎn)請(qǐng)求的日志不存在于源節(jié)點(diǎn)的日志緩沖區(qū)中,但依然存在于源節(jié)點(diǎn)的日志文件中,兩節(jié)點(diǎn)之間為遠(yuǎn)程追趕狀態(tài)
如果目標(biāo)節(jié)點(diǎn)請(qǐng)求的日志已經(jīng)不再存在于源節(jié)點(diǎn)的日志文件中,目標(biāo)節(jié)點(diǎn)則進(jìn)入全量同步狀態(tài)。
當(dāng)兩節(jié)點(diǎn)處于對(duì)等狀態(tài)時(shí),同步請(qǐng)求在源節(jié)點(diǎn)可以直接從內(nèi)存中獲取數(shù)據(jù),因此目標(biāo)節(jié)點(diǎn)選擇復(fù)制源節(jié)點(diǎn)時(shí),總會(huì)嘗試選擇距離自己當(dāng)前日志點(diǎn)最近的數(shù)據(jù)節(jié)點(diǎn),使其所包含的日志盡量坐落在內(nèi)存中。
數(shù)據(jù)全量同步
在分區(qū)組內(nèi),當(dāng)一個(gè)新的節(jié)點(diǎn)加入分區(qū)組,或者故障節(jié)點(diǎn)重新加入分區(qū)組(故障節(jié)點(diǎn)日志版本與其它節(jié)點(diǎn)相差過大,超過了節(jié)點(diǎn)事務(wù)日志空間的大?。换蛘咧貑l(fā)現(xiàn)故障節(jié)點(diǎn)的數(shù)據(jù)不一致),需要進(jìn)行數(shù)據(jù)全量同步,以保障新的節(jié)點(diǎn)與現(xiàn)有節(jié)點(diǎn)之間數(shù)據(jù)的一致性。
在進(jìn)行數(shù)據(jù)全量同步時(shí)有兩個(gè)節(jié)點(diǎn)參與:
源節(jié)點(diǎn): 為包含有效數(shù)據(jù)的節(jié)點(diǎn)。主節(jié)點(diǎn)并不一定永遠(yuǎn)是同步的源節(jié)點(diǎn)。任何與主節(jié)點(diǎn)處于同步狀態(tài)的從節(jié)點(diǎn)均可作為源節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步。
目標(biāo)節(jié)點(diǎn): 為新加入組,或重新入組的故障節(jié)點(diǎn)。同步時(shí)該節(jié)點(diǎn)下原有的數(shù)據(jù)會(huì)被廢棄。
全量同步發(fā)生時(shí),目標(biāo)節(jié)點(diǎn)會(huì)定期向源節(jié)點(diǎn)請(qǐng)求數(shù)據(jù)。源節(jié)點(diǎn)將數(shù)據(jù)打包后作為大數(shù)據(jù)塊發(fā)送給目標(biāo)節(jié)點(diǎn)。當(dāng)目標(biāo)節(jié)點(diǎn)重做該數(shù)據(jù)塊內(nèi)所有數(shù)據(jù)后,向源節(jié)點(diǎn)請(qǐng)求新的數(shù)據(jù)塊。
為保障源節(jié)點(diǎn)在同步時(shí)可進(jìn)行寫操作,所有已經(jīng)被發(fā)送給目標(biāo)節(jié)點(diǎn)的數(shù)據(jù)頁如果被更改,其更新會(huì)被同步到目標(biāo)節(jié)點(diǎn),以保障全量同步過程中更新的數(shù)據(jù)不會(huì)損失。
同步副本數(shù)
巨杉數(shù)據(jù)庫在實(shí)現(xiàn)數(shù)據(jù)同步的時(shí)候,為了適應(yīng)不同的業(yè)務(wù)場景,可以為每個(gè)集合單獨(dú)設(shè)置ReplSize(寫操作同步副本數(shù))參數(shù)。
ReplSize默認(rèn)值為1。其可選取值如下:
-1:表示寫請(qǐng)求需同步到該復(fù)制組若干活躍的節(jié)點(diǎn)之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。
0:表示寫請(qǐng)求需同步到該復(fù)制組的所有節(jié)點(diǎn)之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。
1 - 7:表示寫請(qǐng)求需同步到該復(fù)制組指定數(shù)量個(gè)節(jié)點(diǎn)之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。
在實(shí)際項(xiàng)目中,為了保證數(shù)據(jù)不丟失,需要把ReplSize設(shè)置為大于1,或者-1。例如,如果一個(gè)集合的ReplSize設(shè)置為2,那么主節(jié)點(diǎn)寫操作必須等到有一個(gè)從節(jié)點(diǎn)返回成功才會(huì)給協(xié)調(diào)節(jié)點(diǎn)返回成功,這樣能夠保證如果此時(shí)主節(jié)點(diǎn)宕機(jī),至少有一個(gè)從節(jié)點(diǎn)已經(jīng)持有了成功的日志數(shù)據(jù),在重新選主時(shí),這個(gè)從節(jié)點(diǎn)根據(jù)LSN最新規(guī)則,必然成為候選者,從而保證數(shù)據(jù)不丟失。
3.3 安全性
巨杉數(shù)據(jù)庫的集群一致性算法為了保證數(shù)據(jù)不錯(cuò)不丟,保證數(shù)據(jù)的安全性,也對(duì)選舉規(guī)則和復(fù)制規(guī)則做了一些限制條件。
選舉限制
前面也提到,在巨杉數(shù)據(jù)庫中節(jié)點(diǎn)想要成為候選節(jié)點(diǎn)并發(fā)起選主請(qǐng)求,必須具備的條件是:自己不是主節(jié)點(diǎn),剩下能與自己心跳通訊的節(jié)點(diǎn)數(shù)量必須大于半數(shù)以上,自己的LSN(日志序列號(hào))比其它節(jié)點(diǎn)的LSN新。這些規(guī)則保證了,新主節(jié)點(diǎn)的數(shù)據(jù)是最新的,而且能夠與大于半數(shù)以上的其它節(jié)點(diǎn)通訊。
日志復(fù)制限制
巨杉數(shù)據(jù)庫在復(fù)制組內(nèi)部采用兩階段提交的算法支持事務(wù)能力,并使用表的配置參數(shù)ReplSize(寫副本數(shù))強(qiáng)制主節(jié)點(diǎn)必須同步成功多少個(gè)從節(jié)點(diǎn)。通過這些手段,巨杉數(shù)據(jù)庫可以保證復(fù)制組內(nèi)部節(jié)點(diǎn)的數(shù)據(jù)和事務(wù)的一致性/完整性。
在日志復(fù)制方面,復(fù)制組的主節(jié)點(diǎn)將保證每一個(gè)日志(包含一個(gè)唯一并遞增的LSN)都能夠按照日志復(fù)制的規(guī)則復(fù)制到從節(jié)點(diǎn)上。例如,如果一張表的ReplSize參數(shù)設(shè)置為2,主節(jié)點(diǎn)保證至少在收到一個(gè)從節(jié)點(diǎn)的日志復(fù)制完成的確認(rèn)后才會(huì)返回成功給協(xié)調(diào)節(jié)點(diǎn),否則返回失??;如果ReplSize設(shè)置為-1,主節(jié)點(diǎn)將在收到所有活動(dòng)從節(jié)點(diǎn)的日志復(fù)制成功的確認(rèn)后才會(huì)返回成功給協(xié)調(diào)節(jié)點(diǎn),否則返回失敗。
在事務(wù)完整性方面,巨杉數(shù)據(jù)庫在復(fù)制組內(nèi)的兩階段提交事務(wù)實(shí)現(xiàn)流程如下:
客戶端使用transBegin()開始事務(wù),并發(fā)送給協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)再發(fā)送給主節(jié)點(diǎn)執(zhí)行,主節(jié)點(diǎn)將生成一個(gè)唯一的事務(wù)ID。
在主節(jié)點(diǎn)接收到第一個(gè)寫操作后(如insert,update,delete),會(huì)產(chǎn)生一條日志記錄(日志記錄中包含了事務(wù)ID)。這條日志記錄將根據(jù)規(guī)則(復(fù)制副本數(shù),即使是ReplSize設(shè)置為1,巨杉數(shù)據(jù)庫在執(zhí)行事務(wù)的時(shí)候都必須保證有一個(gè)從節(jié)點(diǎn)持有了事務(wù)ID的日志記錄)發(fā)送給其它從節(jié)點(diǎn)并確認(rèn)成功。
主節(jié)點(diǎn)將繼續(xù)完成其它操作,任何寫操作都將產(chǎn)生一條新的日志記錄,并根據(jù)復(fù)制規(guī)則發(fā)送給其它從節(jié)點(diǎn)并確認(rèn)成功。
主節(jié)點(diǎn)收到transCommit()指令后,將開始二階段提交。
主節(jié)點(diǎn)首先執(zhí)行第一階段,預(yù)提交(pre-commit)。在此階段將產(chǎn)生一條預(yù)提交日志記錄,并發(fā)送給從節(jié)點(diǎn)并確保從節(jié)點(diǎn)確認(rèn)收到。
然后主節(jié)點(diǎn)執(zhí)行第二階段,真正提交(Snd-Commit)。在此階段會(huì)產(chǎn)生一條提交日志記錄,并發(fā)送給從節(jié)點(diǎn)執(zhí)行并確保從節(jié)點(diǎn)成功收到。當(dāng)這個(gè)階段成功后,整個(gè)事務(wù)才確認(rèn)成功,并返回給協(xié)調(diào)節(jié)點(diǎn)成功。
在整個(gè)事務(wù)過程中,如果有任何違反復(fù)制同步規(guī)則的情況發(fā)生,導(dǎo)致事務(wù)無法進(jìn)行下去(例如:在執(zhí)行插入數(shù)據(jù)的時(shí)候,數(shù)據(jù)所在的表的ReplSize是3,而由于某種原因復(fù)制組包括主節(jié)點(diǎn)在內(nèi)只有2給活動(dòng)節(jié)點(diǎn),那么插入操作將失敗,導(dǎo)數(shù)事務(wù)無法繼續(xù)進(jìn)行),那么將進(jìn)行事務(wù)回滾,把之前已經(jīng)執(zhí)行的操作復(fù)原。
在事務(wù)過程中如果出現(xiàn)主節(jié)點(diǎn)宕機(jī)等情況,巨杉數(shù)據(jù)庫將根據(jù)事務(wù)執(zhí)行的情況在新的主節(jié)點(diǎn)選舉成功后自動(dòng)判斷是繼續(xù)提交事務(wù)還是回滾事務(wù),解決可疑事務(wù)問題。
關(guān)于 SequoiaDB高可用的原理是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。