SequoiaDB高可用的原理是什么-創(chuàng)新互聯(lián)

SequoiaDB高可用的原理是什么,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)一直在為企業(yè)提供服務(wù),多年的磨煉,使我們在創(chuàng)意設(shè)計,成都全網(wǎng)營銷推廣到技術(shù)研發(fā)擁有了開發(fā)經(jīng)驗。我們擅長傾聽企業(yè)需求,挖掘用戶對產(chǎn)品需求服務(wù)價值,為企業(yè)制作有用的創(chuàng)意設(shè)計體驗。核心團隊擁有超過十多年以上行業(yè)經(jīng)驗,涵蓋創(chuàng)意,策化,開發(fā)等專業(yè)領(lǐng)域,公司涉及領(lǐng)域有基礎(chǔ)互聯(lián)網(wǎng)服務(wù)樂山服務(wù)器托管、app開發(fā)定制、手機移動建站、網(wǎng)頁設(shè)計、網(wǎng)絡(luò)整合營銷。


1
包括;主備結(jié)構(gòu)和集群架構(gòu);了解到大名鼎鼎的RAFT算法;然后最重要的,巨杉分布式數(shù)據(jù)庫是如何實一致性的,如何保證在集群環(huán)境中實現(xiàn)數(shù)據(jù)不錯不丟。


2

數(shù)據(jù)庫高可用技術(shù)回顧

數(shù)據(jù)庫系統(tǒng)存儲了一個IT系統(tǒng)的業(yè)務(wù)數(shù)據(jù),可以說是IT系統(tǒng)的大腦。數(shù)據(jù)庫系統(tǒng)的可用性基本決定了IT系統(tǒng)的可用性,如果數(shù)據(jù)庫系統(tǒng)宕機那么整個IT系統(tǒng)就停擺了,甚至如果數(shù)據(jù)庫損壞還可能導(dǎo)致業(yè)務(wù)數(shù)據(jù)丟失,造成極大了經(jīng)濟損失。

傳統(tǒng)的數(shù)據(jù)庫系統(tǒng),如:Oracle,DB2,SQL Server,MySQL等都是為單機環(huán)境設(shè)計的,通常的架構(gòu)是一臺服務(wù)器加上磁盤陣列的模式。在生產(chǎn)環(huán)境中,就算是采用了可靠性非常高的小型機及高端磁盤陣列,也難保數(shù)據(jù)庫系統(tǒng)出現(xiàn)服務(wù)器宕機/掉電/網(wǎng)絡(luò)故障/磁盤陣列故障等問題。就是說,數(shù)據(jù)庫系統(tǒng)在運行的過程中出故障是肯定的。那怎么辦呢?經(jīng)過0101訓練過的IT“攻城獅”們的大腦也是比較直的。一個網(wǎng)絡(luò)會出故障,那么再加一個網(wǎng)絡(luò);一臺服務(wù)器會出問題,那么再加一臺服務(wù)器;一個磁盤陣列一份數(shù)據(jù)會出問題,那么再加一個磁盤陣列一份數(shù)據(jù)。“攻城獅”:“我們的口號是消除單點故障,保證數(shù)據(jù)庫7*24可用”。PM:“又要加錢!”。

經(jīng)過“攻城獅們”的實踐,傳統(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ù)器單點故障。如圖所示:

SequoiaDB高可用的原理是什么

主備服務(wù)器上都安裝了數(shù)據(jù)庫軟件和集群管理軟件,并且都能夠通過SAN網(wǎng)絡(luò)訪問磁盤陣列。在正常情況下,主服務(wù)器啟動數(shù)據(jù)庫進程(備服務(wù)器上并不啟動數(shù)據(jù)庫進程),并訪問存儲在磁盤陣列中的數(shù)據(jù)庫;集群管理軟件在主備服務(wù)器上都啟動,監(jiān)控服務(wù)器/網(wǎng)絡(luò)/IO/數(shù)據(jù)庫進程狀態(tài)并提供一個虛擬IP地址(在主服務(wù)器上)供應(yīng)用訪問。

如果集群管理軟件發(fā)現(xiàn)主服務(wù)器不可用(不可用的情況比較多,如掉電/網(wǎng)絡(luò)斷/內(nèi)存CPU故障/無法訪問磁盤陣列/數(shù)據(jù)庫進程宕機等等),就會啟動切換流程。備服務(wù)器:“嘿嘿,終于輪到我上場了,腳都蹲麻了。”

  • 卸載原來掛載在主服務(wù)器上的磁盤陣列設(shè)備及文件系統(tǒng)。

  • 對數(shù)據(jù)庫文件系統(tǒng)進行檢測后掛載到備服務(wù)器上。

  • 取消主服務(wù)器上配置的虛擬IP,把虛擬IP配置到備服務(wù)器上。

  • 啟動備服務(wù)器上的數(shù)據(jù)庫進程;數(shù)據(jù)庫進程檢查數(shù)據(jù)庫日志,對事務(wù)進行重新提交或者回滾。

  • 備服務(wù)器數(shù)據(jù)庫正常后開始提供服務(wù),切換完成。

優(yōu)缺點

優(yōu)點:架構(gòu)和配置簡單,相對成本較低。

缺點:需要重新掛載文件系統(tǒng),啟動數(shù)據(jù)庫進程,數(shù)據(jù)庫日志檢查,切換時間以分鐘計,如果需要回滾的事務(wù)太多,可能是幾十分鐘,對可用性要求比較高的業(yè)務(wù)無法忍受;備服務(wù)器冷備浪費一臺服務(wù)器資源;磁盤陣列只有一個是單點;數(shù)據(jù)只有一份是單點。


2.2 熱備架構(gòu)

熱備架構(gòu)是主備架構(gòu)的另外一種,在冷備架構(gòu)中加入了另外一臺磁盤陣列存儲多一份的數(shù)據(jù)庫數(shù)據(jù),并且備服務(wù)器的數(shù)據(jù)庫進程是啟動的持續(xù)的對主服務(wù)器發(fā)送的日志進行重用。熱備架構(gòu)的實現(xiàn)包括:IBM DB2 HADR,Oracle DataGurd,MySQL Binglog Replication等。

如圖所示:

 SequoiaDB高可用的原理是什么

正常情況下,業(yè)務(wù)應(yīng)用通過虛擬IP訪問主服務(wù)器,主服務(wù)器訪問自己磁盤陣列中的主數(shù)據(jù)庫;主服務(wù)器數(shù)據(jù)庫進程啟動日志復(fù)制功能,把事務(wù)日志復(fù)制到備服務(wù)器的數(shù)據(jù)庫進程;備服務(wù)器的數(shù)據(jù)庫進程把日志重用到備數(shù)據(jù)庫中,完成數(shù)據(jù)同步。

如果主服務(wù)器不可用,集群管理軟件會啟動切換流程。

  • 集群管理軟件取消主服務(wù)器的虛擬IP配置,并把虛擬IP配置到備服務(wù)器。

  • 被服務(wù)器的數(shù)據(jù)庫進程執(zhí)行切換操作,從備升級到主。

  • 備服務(wù)器的數(shù)據(jù)庫進程完成日志重用后,可用開始提供服務(wù)。


優(yōu)點:由于備服務(wù)器的數(shù)據(jù)庫進程是啟動狀態(tài),并且事務(wù)日志持續(xù)重用,切換時間短(秒級別);數(shù)據(jù)是兩份,排除了磁盤陣列和數(shù)據(jù)的單點;備服務(wù)器一般不能寫但是可以提供讀服務(wù)。缺點:增加了一套磁盤陣列,增加了成本。

2.3 集群架構(gòu)

前面兩種架構(gòu)解決了高可用問題,但是數(shù)據(jù)庫系統(tǒng)都只能進行縱向擴展(增加單個服務(wù)器的CPU,內(nèi)存),不能進行橫向擴展(增加服務(wù)器)的方式實現(xiàn)性能擴充。

客戶:”我要橫向擴展“。

攻城獅:”我好難啊,但是可以有“。

通過在數(shù)據(jù)庫系統(tǒng)中提供共享存儲的能力,如:IBM DB2 pureScale,Oracle RAC,多臺服務(wù)器上的數(shù)據(jù)庫進程能夠并行訪問一個共享存儲上的數(shù)據(jù)庫數(shù)據(jù)。

如圖所示:

SequoiaDB高可用的原理是什么

正常情況下,業(yè)務(wù)應(yīng)用可以連接到任意一臺數(shù)據(jù)庫服務(wù)器上執(zhí)行數(shù)據(jù)庫讀寫操作;數(shù)據(jù)庫進程通過并行訪問控制實現(xiàn)對共享磁盤陣列中的數(shù)據(jù)庫的并行讀寫。

如果一臺服務(wù)器不可用,那么連接到這臺服務(wù)器上的應(yīng)用會自動重新連接到另外的數(shù)據(jù)庫服務(wù)器上,實現(xiàn)高可用性。

優(yōu)點:

切換時間短(秒級);可以實現(xiàn)橫向擴展;具有負載均衡能力;

缺點:

橫向擴展能力有限,一般2臺服務(wù)器的案例居多,3臺服務(wù)器以上的案例很少,服務(wù)器太多性能會不增反降;成本較高;配置管理復(fù)雜,DBA需要非常高的數(shù)據(jù)庫管理能力。


3

巨杉分布式數(shù)據(jù)庫的高可用技術(shù)

小伙伴們可能要問:”傳統(tǒng)數(shù)據(jù)庫已經(jīng)實現(xiàn)了高可用和橫向擴展,為啥要用分布式數(shù)據(jù)庫呢?“

攻城獅:”答。首先,傳統(tǒng)數(shù)據(jù)庫橫向擴展能力有限一般2-3臺服務(wù)器,無法應(yīng)對現(xiàn)在的大數(shù)據(jù)場景;其次,貴啊?;◣装偃f用2臺小型機加高端磁盤陣列加ORACLE RAC搭建一個核心數(shù)據(jù)庫,為了穩(wěn)定性也就罷了,但是需要處理幾百TB數(shù)據(jù),需要幾十上百臺服務(wù)器的數(shù)據(jù)庫系統(tǒng)怎么搞?“

巨杉數(shù)據(jù)庫:”該我登場了。不需要磁盤整理,不需要SAN網(wǎng)絡(luò),使用PC服務(wù)器加內(nèi)置磁盤加分布式數(shù)據(jù)庫軟件,實現(xiàn)低成本/高可用性/高可擴展性/高性能的數(shù)據(jù)庫系統(tǒng)。歐耶!“

由于采用了PC服務(wù)器加內(nèi)置磁盤的方式,數(shù)據(jù)一致性和高可用是分布式數(shù)據(jù)庫設(shè)計里面最重要的一環(huán)。這里我們將討論巨杉數(shù)據(jù)庫的高可用實現(xiàn)技術(shù)。巨杉數(shù)據(jù)庫的高可用技術(shù)原理與RAFT算法類似,借鑒了RAFT選舉算法進行了優(yōu)化,以便能夠更好的支持分布式數(shù)據(jù)庫的場景。

3.1 Raft算法

RAFT是一種為了管理復(fù)制日志的一致性的算法。那么RAFT算法是怎么來的了。在RAFT算法出現(xiàn)之前,Paxos算法統(tǒng)治著一致性算法鄰域,但是Paxos的顯著缺點是”十分難于理解“,當然也就難于實現(xiàn)。2013年,斯坦福的Diego Ongaro和John Ousterhout以易于理解為目標設(shè)計了RAFT一致性算法,并發(fā)表論文《In Search of an Understandable Consensus Algorithm》。RAFT算法的易于理解和易于實現(xiàn)使得其在業(yè)界得到了廣泛的應(yīng)用,并在這些實踐中證明了算法的正確性。給大佬們點贊,大佬們的想法是”這個世界給不了我想要的,那我就改變這個世界“。

這里將簡單介紹一下RAFT算法的原理,以幫助大家理解巨杉分布式數(shù)據(jù)庫的高可用性。如果想詳細的了解RAFT算法可以參考github上的文章:

https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md

RAFT算法的設(shè)計思路就是復(fù)雜問題簡單化,把一組服務(wù)器的數(shù)據(jù)一致性問題分解為3個小問題。這3小問題包括:

  • 領(lǐng)導(dǎo)選舉:當現(xiàn)存的領(lǐng)導(dǎo)人宕機的時候,一個新的領(lǐng)導(dǎo)人需要被選舉出來

  • 日志復(fù)制:領(lǐng)導(dǎo)人必須從客戶端接收日志然后復(fù)制到集群中的其他節(jié)點,并且強制要求其他節(jié)點的日志保持和自己相同。

  • 安全性:在 Raft 中安全性的關(guān)鍵是狀態(tài)機安全:如果有任何的服務(wù)器節(jié)點已經(jīng)應(yīng)用了一個確定的日志條目到它的狀態(tài)機中,那么其他服務(wù)器節(jié)點不能在同一個日志索引位置應(yīng)用一個不同的指令。


通過解決上面的3個小問題來,Raft解決了一致性這個大問題。
Raft算法還簡化了復(fù)制狀態(tài)機的數(shù)量,每臺服務(wù)器一定會處于三種狀態(tài):領(lǐng)導(dǎo)人(Leader),候選人(Candidate),追隨者(Follower)。狀態(tài)的轉(zhuǎn)換如圖所示:

SequoiaDB高可用的原理是什么

追隨者只響應(yīng)其他服務(wù)器的請求。如果追隨者沒有收到任何消息,它會成為一個候選人并且開始一次選舉。收到大多數(shù)服務(wù)器投票的候選人會成為新的領(lǐng)導(dǎo)人。領(lǐng)導(dǎo)人在它們宕機之前會一直保持領(lǐng)導(dǎo)人的狀態(tài)。

3.1.1 領(lǐng)導(dǎo)者選舉

RAFT算法建議一組服務(wù)器至少包括5臺服務(wù)器,這樣在有2臺服務(wù)器宕機的情況下,集群任然能夠提供服務(wù)。服務(wù)器的狀態(tài)只能是3中狀態(tài)中的一種,并且在一個集群里只能有一個領(lǐng)導(dǎo)人。集群服務(wù)器之間通過心跳信息相互了解狀態(tài)情況并觸發(fā)選舉。當服務(wù)器程序啟動時,他們都是跟隨者身份。一個服務(wù)器節(jié)點繼續(xù)保持著跟隨者狀態(tài)只要他從領(lǐng)導(dǎo)人或者候選者處接收到有效的 RPCs。領(lǐng)導(dǎo)者周期性的向所有跟隨者發(fā)送心跳包(即不包含日志項內(nèi)容的附加日志項 RPCs)來維持自己的權(quán)威。如果一個跟隨者在一段時間里沒有接收到任何消息,也就是選舉超時,那么他就會認為系統(tǒng)中沒有可用的領(lǐng)導(dǎo)者,并且發(fā)起選舉以選出新的領(lǐng)導(dǎo)者。

要開始一次選舉過程,跟隨者先要增加自己的當前任期號并且轉(zhuǎn)換到候選人狀態(tài)。然后他會并行的向集群中的其他服務(wù)器節(jié)點發(fā)送請求投票的 RPCs 來給自己投票。候選人會繼續(xù)保持著當前狀態(tài)直到以下三件事情之一發(fā)生:(a) 他自己贏得了這次的選舉,(b) 其他的服務(wù)器成為領(lǐng)導(dǎo)者,(c) 一段時間之后沒有任何一個獲勝的人。候選人必須獲得集群中的一半服務(wù)器以上的投票才能成為領(lǐng)導(dǎo)人。

3.1.2 日志復(fù)制

一旦一個領(lǐng)導(dǎo)人被選舉出來,他就開始為客戶端提供服務(wù)??蛻舳说拿恳粋€請求都包含一條被復(fù)制狀態(tài)機執(zhí)行的指令。領(lǐng)導(dǎo)人把這條指令作為一條新的日志條目附加到日志中去,然后并行的發(fā)起附加條目 RPCs 給其他的服務(wù)器,讓他們復(fù)制這條日志條目。當這條日志條目被安全的復(fù)制(下面會介紹),領(lǐng)導(dǎo)人會應(yīng)用這條日志條目到它的狀態(tài)機中然后把執(zhí)行的結(jié)果返回給客戶端。如果跟隨者崩潰或者運行緩慢,再或者網(wǎng)絡(luò)丟包,領(lǐng)導(dǎo)人會不斷的重復(fù)嘗試附加日志條目 RPCs (盡管已經(jīng)回復(fù)了客戶端)直到所有的跟隨者都最終存儲了所有的日志條目。

領(lǐng)導(dǎo)人來決定什么時候把日志條目應(yīng)用到狀態(tài)機中是安全的;這種日志條目被稱為已提交。Raft 算法保證所有已提交的日志條目都是持久化的并且最終會被所有可用的狀態(tài)機執(zhí)行。在領(lǐng)導(dǎo)人將創(chuàng)建的日志條目復(fù)制到大多數(shù)的服務(wù)器上的時候,日志條目就會被提交。同時,領(lǐng)導(dǎo)人的日志中之前的所有日志條目也都會被提交,包括由其他領(lǐng)導(dǎo)人創(chuàng)建的條目。領(lǐng)導(dǎo)人跟蹤了大的將會被提交的日志項的索引,并且索引值會被包含在未來的所有附加日志 RPCs (包括心跳包),這樣其他的服務(wù)器才能最終知道領(lǐng)導(dǎo)人的提交位置。一旦跟隨者知道一條日志條目已經(jīng)被提交,那么他也會將這個日志條目應(yīng)用到本地的狀態(tài)機中(按照日志的順序)。

日志復(fù)制機制展示出了一致性特性:Raft 能夠接受,復(fù)制并應(yīng)用新的日志條目只要大部分的機器是工作的;在通常的情況下,新的日志條目可以在一次 RPC 中被復(fù)制給集群中的大多數(shù)機器;并且單個的緩慢的跟隨者不會影響整體的性能。


3.1.3 安全性

然而,到目前為止描述的機制并不能充分的保證每一個狀態(tài)機會按照相同的順序執(zhí)行相同的指令。例如,一個跟隨者可能會進入不可用狀態(tài)同時領(lǐng)導(dǎo)人已經(jīng)提交了若干的日志條目,然后這個跟隨者可能會被選舉為領(lǐng)導(dǎo)人并且覆蓋這些日志條目;因此,不同的狀態(tài)機可能會執(zhí)行不同的指令序列。

這一節(jié)通過在領(lǐng)導(dǎo)選舉的時候增加一些限制來完善 Raft 算法。這一限制保證了任何的領(lǐng)導(dǎo)人對于給定的任期號,都擁有了之前任期的所有被提交的日志條目。增加這一選舉時的限制,我們對于提交時的規(guī)則也更加清晰。最終,我們將展示對于領(lǐng)導(dǎo)人完整特性的簡要證明,并且說明領(lǐng)導(dǎo)人完整性特性是如何引導(dǎo)復(fù)制狀態(tài)機做出正確行為的。

  • 選舉安全性

Raft 使用了一種更加簡單的方法,它可以保證所有之前的任期號中已經(jīng)提交的日志條目在選舉的時候都會出現(xiàn)在新的領(lǐng)導(dǎo)人中,不需要傳送這些日志條目給領(lǐng)導(dǎo)人。這意味著日志條目的傳送是單向的,只從領(lǐng)導(dǎo)人傳給跟隨者,并且領(lǐng)導(dǎo)人從不會覆蓋自身本地日志中已經(jīng)存在的條目。

Raft 使用投票的方式來阻止一個候選人贏得選舉除非這個候選人包含了所有已經(jīng)提交的日志條目。候選人為了贏得選舉必須聯(lián)系集群中的大部分節(jié)點,這意味著每一個已經(jīng)提交的日志條目在這些服務(wù)器節(jié)點中肯定存在于至少一個節(jié)點上。如果候選人的日志至少和大多數(shù)的服務(wù)器節(jié)點一樣新(這個新的定義會在下面討論),那么他一定持有了所有已經(jīng)提交的日志條目。請求投票 RPC 實現(xiàn)了這樣的限制:RPC 中包含了候選人的日志信息,然后投票人會拒絕掉那些日志沒有自己新的投票請求。

Raft 通過比較兩份日志中最后一條日志條目的索引值和任期號定義誰的日志比較新。如果兩份日志最后的條目的任期號不同,那么任期號大的日志更加新。如果兩份日志最后的條目任期號相同,那么日志比較長的那個就更加新。

  • 提交之前任期內(nèi)的日志條目

RAFT中領(lǐng)導(dǎo)人知道一條當前任期內(nèi)的日志記錄是可以被提交的,只要它被存儲到了大多數(shù)的服務(wù)器上。如果一個領(lǐng)導(dǎo)人在提交日志條目之前崩潰了,未來后續(xù)的領(lǐng)導(dǎo)人會繼續(xù)嘗試復(fù)制這條日志記錄。RAFT的領(lǐng)導(dǎo)人選舉機制保證了新領(lǐng)導(dǎo)人的日志中必然包含了前一個任期的已經(jīng)復(fù)制到大多數(shù)服務(wù)器的最新的任期號和最新的日志條目,這樣新領(lǐng)導(dǎo)人就可以通過日志匹配特性,把之前任期的日志條目復(fù)制到其它服務(wù)器上,實現(xiàn)間接提交。

3.2 巨杉數(shù)據(jù)庫的高可用實現(xiàn)

由于分布式數(shù)據(jù)庫必須具有數(shù)據(jù)庫的ACID(原子性,一致性,隔離性,持久性)及分布式事務(wù)能力,并且還需要提供高性能的并行計算能力,其場景遠比RAFT算法中提到的復(fù)雜的多。

例如:RAFT算法通過保證日志的順序來保證各個節(jié)點數(shù)據(jù)的一致性,但是在數(shù)據(jù)庫的事務(wù)并行執(zhí)行過程中,每個事務(wù)都可能產(chǎn)生多個日志記錄,多個事務(wù)的日志記錄很可能是交叉產(chǎn)生的而不是順序的,要在分布式環(huán)境中保持事務(wù)的原子性,就要求一個事務(wù)產(chǎn)生的所有日志記錄是可追蹤的,在每個節(jié)點上這些日志都必須存在,這樣在事務(wù)提交或者回滾的時候才能夠在每個節(jié)點上保持原子性。在事務(wù)執(zhí)行過程中,有可能會更新大量數(shù)據(jù)(批處理事務(wù)),這些更新操作在分布式數(shù)據(jù)庫中不可能采用等到主節(jié)點執(zhí)行完成,然后再復(fù)制到從節(jié)點的方法,這種方法的執(zhí)行性能太差,無法滿足業(yè)務(wù)需求。巨杉數(shù)據(jù)庫的做法是事務(wù)中的每個寫操作都會產(chǎn)生一個日志記錄,主節(jié)點會把這些日志記錄復(fù)制到從節(jié)點重做,并不會等到事務(wù)提交才開始復(fù)制重做,然后在事務(wù)提交的時候,在復(fù)制組內(nèi)部實現(xiàn)二階段提交算法,保證事務(wù)在復(fù)制組中的原子性和一致性。

另外,RAFT算法中的命令提交成功條件是:集群中的大部分服務(wù)器持有了這條命令的日志記錄。RAFT算法能保證集群是最終一致的,但不保證某個時刻集群是一致的。這種機制在實現(xiàn)集群災(zāi)備的時候會有問題。例如:在5臺服務(wù)器的集群中,3臺在中心A,2臺在中心B,如果領(lǐng)導(dǎo)人在中心A中,那么A中的3臺服務(wù)器處于同一個網(wǎng)絡(luò),通常情況下日志復(fù)制時間都要比處于遠端中心B的2臺服務(wù)器短,也就是說不能保證中心B的服務(wù)器中必定持有最新的日志記錄,如果中心A出現(xiàn)災(zāi)難事故,無法恢復(fù),那么中心B中的服務(wù)器的數(shù)據(jù)是不完整的。這中情況對于某些業(yè)務(wù)(銀行賬務(wù))是無法接受的。巨杉數(shù)據(jù)庫的做法是設(shè)置寫副本數(shù)參數(shù),強制要求必須有多少個節(jié)點都持有最新日志記錄,才算是復(fù)制成功。

所以,巨杉分布式數(shù)據(jù)庫在節(jié)點選舉的實現(xiàn)中優(yōu)化了RAFT算法,而在數(shù)據(jù)同步/日志復(fù)制則完全開發(fā)了自己的算法。在巨杉分布式數(shù)據(jù)庫的架構(gòu)中,主節(jié)點對應(yīng)了RAFT算法中的領(lǐng)導(dǎo)人,從節(jié)點對應(yīng)跟隨人,候選人是一樣的;巨杉數(shù)據(jù)庫的復(fù)制日志對應(yīng)了RAFT算法中的日志記錄;巨杉數(shù)據(jù)庫的復(fù)制組對應(yīng)了一個RAFT算法中的一組服務(wù)器。巨杉數(shù)據(jù)庫在一個集群里面支持多個復(fù)制組,每個復(fù)制組都可以看作是一組RAFT算法的服務(wù)器。

巨杉分布式數(shù)據(jù)庫的節(jié)點類型分為:協(xié)調(diào)節(jié)點,編目節(jié)點,數(shù)據(jù)節(jié)點。其中,多個協(xié)調(diào)節(jié)點的任務(wù)是接收命令,并分發(fā)命令到編目節(jié)點和數(shù)據(jù)節(jié)點,本身不保存數(shù)據(jù),相互之間也沒有關(guān)系,所以不需要考慮可用性問題。編目節(jié)點其實就是一種特殊的數(shù)據(jù)節(jié)點,其高可用性是和數(shù)據(jù)節(jié)點一樣的。協(xié)調(diào)節(jié)點可以看作是數(shù)據(jù)節(jié)點復(fù)制組的客戶端。

巨杉分布式數(shù)據(jù)庫也是通過解決3個小問題,從而實現(xiàn)了集群數(shù)據(jù)一致性這個大問題的。

3.2.1 節(jié)點選舉

巨杉數(shù)據(jù)庫的復(fù)制組可以包含1個到7個數(shù)據(jù)節(jié)點,但是如果要提供高可用特性復(fù)制組的節(jié)點數(shù)量必須大于等于3。每個復(fù)制組在同一時間只會有一個主節(jié)點,其它的都是從節(jié)點,如果處于選主階段,每個從節(jié)點都可以是候選節(jié)點。巨杉數(shù)據(jù)庫選主也是采用同組節(jié)點投票的方式,獲得半數(shù)以上選票的節(jié)點成為主節(jié)點。

為了保證選主成功并且選出的主節(jié)點包含了最新的數(shù)據(jù)庫日志,巨杉數(shù)據(jù)庫在RAFT算法的基礎(chǔ)上做了一些優(yōu)化,特別是在候選節(jié)點的資格選擇上。

從節(jié)點要成為候選節(jié)點并發(fā)起選舉請求必須具有的條件是:自己不是主節(jié)點,剩下能與自己心跳通訊的節(jié)點數(shù)量必須大于半數(shù)以上,自己的LSN(日志序列號)比其它節(jié)點的LSN新。復(fù)制組在主節(jié)點存在的情況下不能自動發(fā)起選舉請求(可以采用手工發(fā)起的方式切換主節(jié)點),只有當主節(jié)點不可用的情況下,從節(jié)點才可以發(fā)起選主請求。如果是集群分裂的情況,比如5個節(jié)點由于網(wǎng)絡(luò)原因分裂為相互不通的2節(jié)點集群和3節(jié)點集群,如果當前主節(jié)點在3節(jié)點的集群中,那么由于此集群的節(jié)點存活數(shù)大于半數(shù),不會發(fā)生選主,如果當前主節(jié)點在2節(jié)點的集群中,那么主節(jié)點將自動降為從節(jié)點,并且3節(jié)點的集群將發(fā)起選主請求,重新選擇一個主節(jié)點。

在復(fù)制組所有節(jié)點正常的時候,每個節(jié)點都會通過共享心跳信息sharing-beat共享狀態(tài)信息。共享心跳信息包括:心跳 ID、自身開始LSN、自身終止LSN、時間戳、數(shù)據(jù)組版本號、自身當前的角色和同步狀態(tài)。如圖所示:

 SequoiaDB高可用的原理是什么

每個節(jié)點都維護一張 status-sharing table 表,用來記錄節(jié)點狀態(tài)。sharing-beat 每2秒發(fā)送一次,采集應(yīng)答信息,若連續(xù)兩次未收到應(yīng)答信息,則認為節(jié)點宕機。節(jié)點進程中的ReplReader(復(fù)制監(jiān)聽線程)負責節(jié)點狀態(tài)信息的接收和發(fā)送。

從節(jié)點發(fā)起選主之前,會檢查共享心跳信息中本節(jié)點的LSN以及其它從節(jié)點的LSN,如果自己LSN大于等于其它從節(jié)點的LSN,就可以發(fā)起選主請求,否則就不發(fā)起。

在選主中,如果多個候選從節(jié)點的LSN相同,并且都發(fā)起了請求,那么將比較各從節(jié)點的權(quán)重配置參數(shù)(weight)。復(fù)制組的每個節(jié)點都可單獨配置不同的權(quán)重,從0到100,數(shù)字越大權(quán)重越高,相同LSN的從節(jié)點,權(quán)重高的選主成功。

如果多個從節(jié)點的LSN相同,權(quán)重配置也相同,那么將比較這些從節(jié)點的節(jié)點號,在創(chuàng)建節(jié)點的時候,每個節(jié)點的節(jié)點號是不同的,節(jié)點號大的將選主成功。

從上面可以看出巨杉分布式數(shù)據(jù)庫在選主中,優(yōu)化了選主流程,在RAFT算法的基礎(chǔ)上增加了權(quán)重和節(jié)點號的判斷,這樣就不會出現(xiàn)RAFT算法中多個節(jié)點選主票數(shù)相同導(dǎo)致失敗的情況。

下面舉一個簡單例子,描述一下巨杉數(shù)據(jù)庫的選主流程。

如圖所示,一個3節(jié)點的復(fù)制組,包括:主節(jié)點A,從節(jié)點B,從節(jié)點C。在正常情況下,三個節(jié)點通過心跳共享狀態(tài)信息。如果主節(jié)點A由于某種原因故障(服務(wù)器掉電/網(wǎng)絡(luò)故障/磁盤故障等等)將自動降為從節(jié)點,集群開始重新選主。

SequoiaDB高可用的原理是什么

兩個從節(jié)點,發(fā)現(xiàn)2輪沒有收到主節(jié)點的心跳信息,則認為主節(jié)點宕機。

從節(jié)點B:”嘿嘿,主節(jié)點掛了,我有機會當老大了。我看看,我是從節(jié)點,LSN是最新的。嗨,C兄,我的LSN是XXX,我要當老大,你同意嗎?“

從節(jié)點C:”嘎嘎,老大掛了!不當大哥很多年,有點想念。我看看,我是從節(jié)點,LSN是最新的,有機會。嗨,B兄,我的LSN是XXX,我要當老大,你同意嗎?“

從節(jié)點B:”C兄也想當老大,LSN和我一樣。嗨C兄,我的LSN也是XXX,我的權(quán)重是80,還是我當?”

從節(jié)點C:“B兄不好意思,我的權(quán)重也是80,我也想當。我的節(jié)點號是1008?!?/p>

從節(jié)點B:“C兄的節(jié)點號是1008,我的是1006;輸了輸了,C兄你是老大了?!?/p>

從節(jié)點C:“我自己投了自己一票,B兄投了我一篇,現(xiàn)在是2票,大于3/2+1,嗯夠了。嗨B兄我是老大了?!?/p>

從節(jié)點B:“收到,老大?!?/p>

重新選主成功后,新主節(jié)點會通知編目節(jié)點變更主節(jié)點信息;協(xié)調(diào)節(jié)點會從編目節(jié)點同步節(jié)點狀態(tài)信息,并連接到新主節(jié)點;協(xié)調(diào)節(jié)點也可以通過遍歷節(jié)點的方式來獲得新主節(jié)點信息。這樣就在主節(jié)點宕機后實現(xiàn)了高可用能力。原主節(jié)點A恢復(fù)后,自動成為從節(jié)點。

3.2.2 日志復(fù)制

巨杉數(shù)據(jù)庫的日志復(fù)制機制與RAFT的日志復(fù)制機制不同。首先,RAFT算法的日志總是從領(lǐng)導(dǎo)人(Leader)發(fā)送給追隨者(Follower),追隨者之間不會交換日志數(shù)據(jù);而巨杉數(shù)據(jù)庫的日志復(fù)制在源節(jié)點(發(fā)送日志的節(jié)點)和目標節(jié)點(請求日志的節(jié)點)之間進行,并且是目標節(jié)點主動向源節(jié)點請求日志數(shù)據(jù),源節(jié)點大多數(shù)情況是主節(jié)點,但其它從節(jié)點也可以是源節(jié)點,目標節(jié)點只能是從節(jié)點。其次,RAFT算法中如果領(lǐng)導(dǎo)人沒有追隨者的日志復(fù)制返回信息,領(lǐng)導(dǎo)人會持續(xù)的給這個追隨者發(fā)送日志直到收到返回信息,都是增量復(fù)制;而巨杉數(shù)據(jù)庫的數(shù)據(jù)同步復(fù)制可以是日志增量復(fù)制,也可能觸發(fā)數(shù)據(jù)全量同步。

巨杉數(shù)據(jù)庫的日志復(fù)制不采用RAFT算法是因為其在分布式數(shù)據(jù)庫的場景中并不適合。例如,如果某個從節(jié)點宕機,而按照RAFT算法主節(jié)點持續(xù)的向此從節(jié)點發(fā)送日志信息,而日志數(shù)據(jù)又很大,那么就會占用主節(jié)點大量的CPU/內(nèi)存/網(wǎng)絡(luò)資源,嚴重的影響主節(jié)點的性能,有可能造成阻塞;巨杉數(shù)據(jù)庫采用從節(jié)點請求的方式,只有從節(jié)點是正常狀態(tài)的時候才會請求新的日志數(shù)據(jù),并清楚的給出需要哪些日志數(shù)據(jù),不會造成重復(fù)發(fā)送問題,并且從節(jié)點可以作為源節(jié)點以可以大大減少主節(jié)點的工作負載。另外,由于實際環(huán)境中,存儲空間是有限的,數(shù)據(jù)庫能夠配置的日志空間也是有限的,所以巨杉數(shù)據(jù)庫的數(shù)據(jù)同步模式分為日志增量同步和數(shù)據(jù)全量同步兩種方式。如果目標節(jié)點需要同步的數(shù)據(jù)都包含在源節(jié)點的復(fù)制日志空間中,就進行日志增量同步;如果數(shù)據(jù)已經(jīng)不在復(fù)制日志空間中,那么需要進行全量同步。最重要的是,分布式數(shù)據(jù)庫要求支持ACID及事務(wù)的能力,其場景比RAFT算法描述的日志復(fù)制場景更復(fù)雜,巨杉數(shù)據(jù)庫采用兩階段提交的算法在兼顧性能和事務(wù)一致性的情況下支持復(fù)制組內(nèi)部的事務(wù)能力。

  • 日志增量同步模式

在數(shù)據(jù)節(jié)點和編目節(jié)點中,任何數(shù)據(jù)增刪改操作均會寫入日志。SequoiaDB 會首先將日志寫入日志緩沖區(qū),然后將其異步寫入本地磁盤。

每個數(shù)據(jù)復(fù)制會在兩個節(jié)點間進行:

源節(jié)點: 為包含新數(shù)據(jù)的節(jié)點。主節(jié)點并不一定永遠是復(fù)制的源節(jié)點。

目標節(jié)點: 為請求進行數(shù)據(jù)復(fù)制的節(jié)點。

復(fù)制過程中,目標節(jié)點選擇一個與其最接近的節(jié)點(在共享的節(jié)點狀態(tài)表中,包含了每個節(jié)點的開始LSN和結(jié)束LSN可用計算哪個與自己最接近),然后向其發(fā)送一個復(fù)制請求。源節(jié)點接到復(fù)制請求后,會將目標節(jié)點請求的同步點之后的日志記錄打包并發(fā)送給目標節(jié)點,目標節(jié)點接收到數(shù)據(jù)包后會重新處理日志中的所有操作。

節(jié)點之間的復(fù)制有兩個狀態(tài):

對等狀態(tài)(PEER):當目標節(jié)點請求的日志依然存在于源節(jié)點的日志緩沖區(qū)中,兩節(jié)點之間為對等狀態(tài)

遠程追趕狀態(tài)(RemoteCatchup):當目標節(jié)點請求的日志不存在于源節(jié)點的日志緩沖區(qū)中,但依然存在于源節(jié)點的日志文件中,兩節(jié)點之間為遠程追趕狀態(tài)

如果目標節(jié)點請求的日志已經(jīng)不再存在于源節(jié)點的日志文件中,目標節(jié)點則進入全量同步狀態(tài)。

當兩節(jié)點處于對等狀態(tài)時,同步請求在源節(jié)點可以直接從內(nèi)存中獲取數(shù)據(jù),因此目標節(jié)點選擇復(fù)制源節(jié)點時,總會嘗試選擇距離自己當前日志點最近的數(shù)據(jù)節(jié)點,使其所包含的日志盡量坐落在內(nèi)存中。

  • 數(shù)據(jù)全量同步

在分區(qū)組內(nèi),當一個新的節(jié)點加入分區(qū)組,或者故障節(jié)點重新加入分區(qū)組(故障節(jié)點日志版本與其它節(jié)點相差過大,超過了節(jié)點事務(wù)日志空間的大?。换蛘咧貑l(fā)現(xiàn)故障節(jié)點的數(shù)據(jù)不一致),需要進行數(shù)據(jù)全量同步,以保障新的節(jié)點與現(xiàn)有節(jié)點之間數(shù)據(jù)的一致性。

在進行數(shù)據(jù)全量同步時有兩個節(jié)點參與:

源節(jié)點: 為包含有效數(shù)據(jù)的節(jié)點。主節(jié)點并不一定永遠是同步的源節(jié)點。任何與主節(jié)點處于同步狀態(tài)的從節(jié)點均可作為源節(jié)點進行數(shù)據(jù)同步。

目標節(jié)點: 為新加入組,或重新入組的故障節(jié)點。同步時該節(jié)點下原有的數(shù)據(jù)會被廢棄。

全量同步發(fā)生時,目標節(jié)點會定期向源節(jié)點請求數(shù)據(jù)。源節(jié)點將數(shù)據(jù)打包后作為大數(shù)據(jù)塊發(fā)送給目標節(jié)點。當目標節(jié)點重做該數(shù)據(jù)塊內(nèi)所有數(shù)據(jù)后,向源節(jié)點請求新的數(shù)據(jù)塊。

為保障源節(jié)點在同步時可進行寫操作,所有已經(jīng)被發(fā)送給目標節(jié)點的數(shù)據(jù)頁如果被更改,其更新會被同步到目標節(jié)點,以保障全量同步過程中更新的數(shù)據(jù)不會損失。

  • 同步副本數(shù)

巨杉數(shù)據(jù)庫在實現(xiàn)數(shù)據(jù)同步的時候,為了適應(yīng)不同的業(yè)務(wù)場景,可以為每個集合單獨設(shè)置ReplSize(寫操作同步副本數(shù))參數(shù)。

ReplSize默認值為1。其可選取值如下:

  • -1:表示寫請求需同步到該復(fù)制組若干活躍的節(jié)點之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。

  • 0:表示寫請求需同步到該復(fù)制組的所有節(jié)點之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。

  • 1 - 7:表示寫請求需同步到該復(fù)制組指定數(shù)量個節(jié)點之后,數(shù)據(jù)庫寫操作才返回應(yīng)答給客戶端。


在實際項目中,為了保證數(shù)據(jù)不丟失,需要把ReplSize設(shè)置為大于1,或者-1。例如,如果一個集合的ReplSize設(shè)置為2,那么主節(jié)點寫操作必須等到有一個從節(jié)點返回成功才會給協(xié)調(diào)節(jié)點返回成功,這樣能夠保證如果此時主節(jié)點宕機,至少有一個從節(jié)點已經(jīng)持有了成功的日志數(shù)據(jù),在重新選主時,這個從節(jié)點根據(jù)LSN最新規(guī)則,必然成為候選者,從而保證數(shù)據(jù)不丟失。

3.3 安全性

巨杉數(shù)據(jù)庫的集群一致性算法為了保證數(shù)據(jù)不錯不丟,保證數(shù)據(jù)的安全性,也對選舉規(guī)則和復(fù)制規(guī)則做了一些限制條件。

  • 選舉限制

前面也提到,在巨杉數(shù)據(jù)庫中節(jié)點想要成為候選節(jié)點并發(fā)起選主請求,必須具備的條件是:自己不是主節(jié)點,剩下能與自己心跳通訊的節(jié)點數(shù)量必須大于半數(shù)以上,自己的LSN(日志序列號)比其它節(jié)點的LSN新。這些規(guī)則保證了,新主節(jié)點的數(shù)據(jù)是最新的,而且能夠與大于半數(shù)以上的其它節(jié)點通訊。

  • 日志復(fù)制限制

巨杉數(shù)據(jù)庫在復(fù)制組內(nèi)部采用兩階段提交的算法支持事務(wù)能力,并使用表的配置參數(shù)ReplSize(寫副本數(shù))強制主節(jié)點必須同步成功多少個從節(jié)點。通過這些手段,巨杉數(shù)據(jù)庫可以保證復(fù)制組內(nèi)部節(jié)點的數(shù)據(jù)和事務(wù)的一致性/完整性。

在日志復(fù)制方面,復(fù)制組的主節(jié)點將保證每一個日志(包含一個唯一并遞增的LSN)都能夠按照日志復(fù)制的規(guī)則復(fù)制到從節(jié)點上。例如,如果一張表的ReplSize參數(shù)設(shè)置為2,主節(jié)點保證至少在收到一個從節(jié)點的日志復(fù)制完成的確認后才會返回成功給協(xié)調(diào)節(jié)點,否則返回失敗;如果ReplSize設(shè)置為-1,主節(jié)點將在收到所有活動從節(jié)點的日志復(fù)制成功的確認后才會返回成功給協(xié)調(diào)節(jié)點,否則返回失敗。

在事務(wù)完整性方面,巨杉數(shù)據(jù)庫在復(fù)制組內(nèi)的兩階段提交事務(wù)實現(xiàn)流程如下:

  • 客戶端使用transBegin()開始事務(wù),并發(fā)送給協(xié)調(diào)節(jié)點,協(xié)調(diào)節(jié)點再發(fā)送給主節(jié)點執(zhí)行,主節(jié)點將生成一個唯一的事務(wù)ID。

  • 在主節(jié)點接收到第一個寫操作后(如insert,update,delete),會產(chǎn)生一條日志記錄(日志記錄中包含了事務(wù)ID)。這條日志記錄將根據(jù)規(guī)則(復(fù)制副本數(shù),即使是ReplSize設(shè)置為1,巨杉數(shù)據(jù)庫在執(zhí)行事務(wù)的時候都必須保證有一個從節(jié)點持有了事務(wù)ID的日志記錄)發(fā)送給其它從節(jié)點并確認成功。

  • 主節(jié)點將繼續(xù)完成其它操作,任何寫操作都將產(chǎn)生一條新的日志記錄,并根據(jù)復(fù)制規(guī)則發(fā)送給其它從節(jié)點并確認成功。

  • 主節(jié)點收到transCommit()指令后,將開始二階段提交。

  • 主節(jié)點首先執(zhí)行第一階段,預(yù)提交(pre-commit)。在此階段將產(chǎn)生一條預(yù)提交日志記錄,并發(fā)送給從節(jié)點并確保從節(jié)點確認收到。

  • 然后主節(jié)點執(zhí)行第二階段,真正提交(Snd-Commit)。在此階段會產(chǎn)生一條提交日志記錄,并發(fā)送給從節(jié)點執(zhí)行并確保從節(jié)點成功收到。當這個階段成功后,整個事務(wù)才確認成功,并返回給協(xié)調(diào)節(jié)點成功。


在整個事務(wù)過程中,如果有任何違反復(fù)制同步規(guī)則的情況發(fā)生,導(dǎo)致事務(wù)無法進行下去(例如:在執(zhí)行插入數(shù)據(jù)的時候,數(shù)據(jù)所在的表的ReplSize是3,而由于某種原因復(fù)制組包括主節(jié)點在內(nèi)只有2給活動節(jié)點,那么插入操作將失敗,導(dǎo)數(shù)事務(wù)無法繼續(xù)進行),那么將進行事務(wù)回滾,把之前已經(jīng)執(zhí)行的操作復(fù)原。
在事務(wù)過程中如果出現(xiàn)主節(jié)點宕機等情況,巨杉數(shù)據(jù)庫將根據(jù)事務(wù)執(zhí)行的情況在新的主節(jié)點選舉成功后自動判斷是繼續(xù)提交事務(wù)還是回滾事務(wù),解決可疑事務(wù)問題。

關(guān)于 SequoiaDB高可用的原理是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道了解更多相關(guān)知識。

本文名稱:SequoiaDB高可用的原理是什么-創(chuàng)新互聯(lián)
轉(zhuǎn)載來源:http://www.muchs.cn/article36/dpgspg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃網(wǎng)站導(dǎo)航、網(wǎng)站排名、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站制作、用戶體驗

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)