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

1
包括;主備結構和集群架構;了解到大名鼎鼎的RAFT算法;然后最重要的,巨杉分布式數據庫是如何實一致性的,如何保證在集群環(huán)境中實現數據不錯不丟。
2
數據庫高可用技術回顧
數據庫系統(tǒng)存儲了一個IT系統(tǒng)的業(yè)務數據,可以說是IT系統(tǒng)的大腦。數據庫系統(tǒng)的可用性基本決定了IT系統(tǒng)的可用性,如果數據庫系統(tǒng)宕機那么整個IT系統(tǒng)就停擺了,甚至如果數據庫損壞還可能導致業(yè)務數據丟失,造成極大了經濟損失。
傳統(tǒng)的數據庫系統(tǒng),如:Oracle,DB2,SQL Server,MySQL等都是為單機環(huán)境設計的,通常的架構是一臺服務器加上磁盤陣列的模式。在生產環(huán)境中,就算是采用了可靠性非常高的小型機及高端磁盤陣列,也難保數據庫系統(tǒng)出現服務器宕機/掉電/網絡故障/磁盤陣列故障等問題。就是說,數據庫系統(tǒng)在運行的過程中出故障是肯定的。那怎么辦呢?經過0101訓練過的IT“攻城獅”們的大腦也是比較直的。一個網絡會出故障,那么再加一個網絡;一臺服務器會出問題,那么再加一臺服務器;一個磁盤陣列一份數據會出問題,那么再加一個磁盤陣列一份數據。“攻城獅”:“我們的口號是消除單點故障,保證數據庫7*24可用”。PM:“又要加錢!”。
經過“攻城獅們”的實踐,傳統(tǒng)數據庫的高可用分為3種架構:冷備架構/熱備架構/集群架構。
2.1 冷備架構
冷備架構是主備架構的一種,通過增加冗余的網絡和服務器,并增加集群管理軟件,如:IBM HACMP,消除網絡和服務器單點故障。如圖所示:

主備服務器上都安裝了數據庫軟件和集群管理軟件,并且都能夠通過San 網絡訪問磁盤陣列。在正常情況下,主服務器啟動數據庫進程(備服務器上并不啟動數據庫進程),并訪問存儲在磁盤陣列中的數據庫;集群管理軟件在主備服務器上都啟動,監(jiān)控服務器/網絡/IO/數據庫進程狀態(tài)并提供一個虛擬IP地址(在主服務器上)供應用訪問。
如果集群管理軟件發(fā)現主服務器不可用(不可用的情況比較多,如掉電/網絡斷/內存CPU故障/無法訪問磁盤陣列/數據庫進程宕機等等),就會啟動切換流程。備服務器:“嘿嘿,終于輪到我上場了,腳都蹲麻了。”
卸載原來掛載在主服務器上的磁盤陣列設備及文件系統(tǒng)。
對數據庫文件系統(tǒng)進行檢測后掛載到備服務器上。
取消主服務器上配置的虛擬IP,把虛擬IP配置到備服務器上。
啟動備服務器上的數據庫進程;數據庫進程檢查數據庫日志,對事務進行重新提交或者回滾。
備服務器數據庫正常后開始提供服務,切換完成。
優(yōu)缺點
優(yōu)點:架構和配置簡單,相對成本較低。
缺點:需要重新掛載文件系統(tǒng),啟動數據庫進程,數據庫日志檢查,切換時間以分鐘計,如果需要回滾的事務太多,可能是幾十分鐘,對可用性要求比較高的業(yè)務無法忍受;備服務器冷備浪費一臺服務器資源;磁盤陣列只有一個是單點;數據只有一份是單點。
2.2 熱備架構
熱備架構是主備架構的另外一種,在冷備架構中加入了另外一臺磁盤陣列存儲多一份的數據庫數據,并且備服務器的數據庫進程是啟動的持續(xù)的對主服務器發(fā)送的日志進行重用。熱備架構的實現包括:IBM DB2 HADR,Oracle DataGurd,MySQL Binglog Replication等。
如圖所示:

正常情況下,業(yè)務應用通過虛擬IP訪問主服務器,主服務器訪問自己磁盤陣列中的主數據庫;主服務器數據庫進程啟動日志復制功能,把事務日志復制到備服務器的數據庫進程;備服務器的數據庫進程把日志重用到備數據庫中,完成數據同步。
如果主服務器不可用,集群管理軟件會啟動切換流程。
集群管理軟件取消主服務器的虛擬IP配置,并把虛擬IP配置到備服務器。
被服務器的數據庫進程執(zhí)行切換操作,從備升級到主。
備服務器的數據庫進程完成日志重用后,可用開始提供服務。
優(yōu)點:由于備服務器的數據庫進程是啟動狀態(tài),并且事務日志持續(xù)重用,切換時間短(秒級別);數據是兩份,排除了磁盤陣列和數據的單點;備服務器一般不能寫但是可以提供讀服務。缺點:增加了一套磁盤陣列,增加了成本。
2.3 集群架構
前面兩種架構解決了高可用問題,但是數據庫系統(tǒng)都只能進行縱向擴展(增加單個服務器的CPU,內存),不能進行橫向擴展(增加服務器)的方式實現性能擴充。
客戶:”我要橫向擴展“。
攻城獅:”我好難啊,但是可以有“。
通過在數據庫系統(tǒng)中提供共享存儲的能力,如:IBM DB2 pureScale,Oracle RAC,多臺服務器上的數據庫進程能夠并行訪問一個共享存儲上的數據庫數據。
如圖所示:

正常情況下,業(yè)務應用可以連接到任意一臺數據庫服務器上執(zhí)行數據庫讀寫操作;數據庫進程通過并行訪問控制實現對共享磁盤陣列中的數據庫的并行讀寫。
如果一臺服務器不可用,那么連接到這臺服務器上的應用會自動重新連接到另外的數據庫服務器上,實現高可用性。
優(yōu)點:
切換時間短(秒級);可以實現橫向擴展;具有負載均衡能力;
缺點:
橫向擴展能力有限,一般2臺服務器的案例居多,3臺服務器以上的案例很少,服務器太多性能會不增反降;成本較高;配置管理復雜,DBA需要非常高的數據庫管理能力。
3
巨杉分布式數據庫的高可用技術
小伙伴們可能要問:”傳統(tǒng)數據庫已經實現了高可用和橫向擴展,為啥要用分布式數據庫呢?“
攻城獅:”答。首先,傳統(tǒng)數據庫橫向擴展能力有限一般2-3臺服務器,無法應對現在的大數據場景;其次,貴啊。花幾百萬用2臺小型機加高端磁盤陣列加ORACLE RAC搭建一個核心數據庫,為了穩(wěn)定性也就罷了,但是需要處理幾百TB數據,需要幾十上百臺服務器的數據庫系統(tǒng)怎么搞?“
巨杉數據庫:”該我登場了。不需要磁盤整理,不需要San 網絡,使用PC服務器加內置磁盤加分布式數據庫軟件,實現低成本/高可用性/高可擴展性/高性能的數據庫系統(tǒng)。歐耶!“
由于采用了PC服務器加內置磁盤的方式,數據一致性和高可用是分布式數據庫設計里面最重要的一環(huán)。這里我們將討論巨杉數據庫的高可用實現技術。巨杉數據庫的高可用技術原理與RAFT算法類似,借鑒了RAFT選舉算法進行了優(yōu)化,以便能夠更好的支持分布式數據庫的場景。
3.1 Raft算法
RAFT是一種為了管理復制日志的一致性的算法。那么RAFT算法是怎么來的了。在RAFT算法出現之前,Paxos算法統(tǒng)治著一致性算法鄰域,但是Paxos的顯著缺點是”十分難于理解“,當然也就難于實現。2013年,斯坦福的Diego Ongaro和John Ousterhout以易于理解為目標設計了RAFT一致性算法,并發(fā)表論文《In Search of an Understandable Consensus Algorithm》。RAFT算法的易于理解和易于實現使得其在業(yè)界得到了廣泛的應用,并在這些實踐中證明了算法的正確性。給大佬們點贊,大佬們的想法是”這個世界給不了我想要的,那我就改變這個世界“。
這里將簡單介紹一下RAFT算法的原理,以幫助大家理解巨杉分布式數據庫的高可用性。如果想詳細的了解RAFT算法可以參考github上的文章:
https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md
RAFT算法的設計思路就是復雜問題簡單化,把一組服務器的數據一致性問題分解為3個小問題。這3小問題包括:
領導選舉:當現存的領導人宕機的時候,一個新的領導人需要被選舉出來
日志復制:領導人必須從客戶端接收日志然后復制到集群中的其他節(jié)點,并且強制要求其他節(jié)點的日志保持和自己相同。
安全性:在 Raft 中安全性的關鍵是狀態(tài)機安全:如果有任何的服務器節(jié)點已經應用了一個確定的日志條目到它的狀態(tài)機中,那么其他服務器節(jié)點不能在同一個日志索引位置應用一個不同的指令。
通過解決上面的3個小問題來,Raft解決了一致性這個大問題。
Raft算法還簡化了復制狀態(tài)機的數量,每臺服務器一定會處于三種狀態(tài):領導人(Leader),候選人(Candidate),追隨者(Follower)。狀態(tài)的轉換如圖所示:

追隨者只響應其他服務器的請求。如果追隨者沒有收到任何消息,它會成為一個候選人并且開始一次選舉。收到大多數服務器投票的候選人會成為新的領導人。領導人在它們宕機之前會一直保持領導人的狀態(tài)。
3.1.1 領導者選舉
RAFT算法建議一組服務器至少包括5臺服務器,這樣在有2臺服務器宕機的情況下,集群任然能夠提供服務。服務器的狀態(tài)只能是3中狀態(tài)中的一種,并且在一個集群里只能有一個領導人。集群服務器之間通過心跳信息相互了解狀態(tài)情況并觸發(fā)選舉。當服務器程序啟動時,他們都是跟隨者身份。一個服務器節(jié)點繼續(xù)保持著跟隨者狀態(tài)只要他從領導人或者候選者處接收到有效的 RPCs。領導者周期性的向所有跟隨者發(fā)送心跳包(即不包含日志項內容的附加日志項 RPCs)來維持自己的權威。如果一個跟隨者在一段時間里沒有接收到任何消息,也就是選舉超時,那么他就會認為系統(tǒng)中沒有可用的領導者,并且發(fā)起選舉以選出新的領導者。
要開始一次選舉過程,跟隨者先要增加自己的當前任期號并且轉換到候選人狀態(tài)。然后他會并行的向集群中的其他服務器節(jié)點發(fā)送請求投票的 RPCs 來給自己投票。候選人會繼續(xù)保持著當前狀態(tài)直到以下三件事情之一發(fā)生:(a) 他自己贏得了這次的選舉,(b) 其他的服務器成為領導者,(c) 一段時間之后沒有任何一個獲勝的人。候選人必須獲得集群中的一半服務器以上的投票才能成為領導人。
3.1.2 日志復制
一旦一個領導人被選舉出來,他就開始為客戶端提供服務。客戶端的每一個請求都包含一條被復制狀態(tài)機執(zhí)行的指令。領導人把這條指令作為一條新的日志條目附加到日志中去,然后并行的發(fā)起附加條目 RPCs 給其他的服務器,讓他們復制這條日志條目。當這條日志條目被安全的復制(下面會介紹),領導人會應用這條日志條目到它的狀態(tài)機中然后把執(zhí)行的結果返回給客戶端。如果跟隨者崩潰或者運行緩慢,再或者網絡丟包,領導人會不斷的重復嘗試附加日志條目 RPCs (盡管已經回復了客戶端)直到所有的跟隨者都最終存儲了所有的日志條目。
領導人來決定什么時候把日志條目應用到狀態(tài)機中是安全的;這種日志條目被稱為已提交。Raft 算法保證所有已提交的日志條目都是持久化的并且最終會被所有可用的狀態(tài)機執(zhí)行。在領導人將創(chuàng)建的日志條目復制到大多數的服務器上的時候,日志條目就會被提交。同時,領導人的日志中之前的所有日志條目也都會被提交,包括由其他領導人創(chuàng)建的條目。領導人跟蹤了大的將會被提交的日志項的索引,并且索引值會被包含在未來的所有附加日志 RPCs (包括心跳包),這樣其他的服務器才能最終知道領導人的提交位置。一旦跟隨者知道一條日志條目已經被提交,那么他也會將這個日志條目應用到本地的狀態(tài)機中(按照日志的順序)。
日志復制機制展示出了一致性特性:Raft 能夠接受,復制并應用新的日志條目只要大部分的機器是工作的;在通常的情況下,新的日志條目可以在一次 RPC 中被復制給集群中的大多數機器;并且單個的緩慢的跟隨者不會影響整體的性能。
3.1.3 安全性
然而,到目前為止描述的機制并不能充分的保證每一個狀態(tài)機會按照相同的順序執(zhí)行相同的指令。例如,一個跟隨者可能會進入不可用狀態(tài)同時領導人已經提交了若干的日志條目,然后這個跟隨者可能會被選舉為領導人并且覆蓋這些日志條目;因此,不同的狀態(tài)機可能會執(zhí)行不同的指令序列。
這一節(jié)通過在領導選舉的時候增加一些限制來完善 Raft 算法。這一限制保證了任何的領導人對于給定的任期號,都擁有了之前任期的所有被提交的日志條目。增加這一選舉時的限制,我們對于提交時的規(guī)則也更加清晰。最終,我們將展示對于領導人完整特性的簡要證明,并且說明領導人完整性特性是如何引導復制狀態(tài)機做出正確行為的。
選舉安全性
Raft 使用了一種更加簡單的方法,它可以保證所有之前的任期號中已經提交的日志條目在選舉的時候都會出現在新的領導人中,不需要傳送這些日志條目給領導人。這意味著日志條目的傳送是單向的,只從領導人傳給跟隨者,并且領導人從不會覆蓋自身本地日志中已經存在的條目。
Raft 使用投票的方式來阻止一個候選人贏得選舉除非這個候選人包含了所有已經提交的日志條目。候選人為了贏得選舉必須聯(lián)系集群中的大部分節(jié)點,這意味著每一個已經提交的日志條目在這些服務器節(jié)點中肯定存在于至少一個節(jié)點上。如果候選人的日志至少和大多數的服務器節(jié)點一樣新(這個新的定義會在下面討論),那么他一定持有了所有已經提交的日志條目。請求投票 RPC 實現了這樣的限制:RPC 中包含了候選人的日志信息,然后投票人會拒絕掉那些日志沒有自己新的投票請求。
Raft 通過比較兩份日志中最后一條日志條目的索引值和任期號定義誰的日志比較新。如果兩份日志最后的條目的任期號不同,那么任期號大的日志更加新。如果兩份日志最后的條目任期號相同,那么日志比較長的那個就更加新。
提交之前任期內的日志條目
RAFT中領導人知道一條當前任期內的日志記錄是可以被提交的,只要它被存儲到了大多數的服務器上。如果一個領導人在提交日志條目之前崩潰了,未來后續(xù)的領導人會繼續(xù)嘗試復制這條日志記錄。RAFT的領導人選舉機制保證了新領導人的日志中必然包含了前一個任期的已經復制到大多數服務器的最新的任期號和最新的日志條目,這樣新領導人就可以通過日志匹配特性,把之前任期的日志條目復制到其它服務器上,實現間接提交。
3.2 巨杉數據庫的高可用實現
由于分布式數據庫必須具有數據庫的ACID(原子性,一致性,隔離性,持久性)及分布式事務能力,并且還需要提供高性能的并行計算能力,其場景遠比RAFT算法中提到的復雜的多。
例如:RAFT算法通過保證日志的順序來保證各個節(jié)點數據的一致性,但是在數據庫的事務并行執(zhí)行過程中,每個事務都可能產生多個日志記錄,多個事務的日志記錄很可能是交叉產生的而不是順序的,要在分布式環(huán)境中保持事務的原子性,就要求一個事務產生的所有日志記錄是可追蹤的,在每個節(jié)點上這些日志都必須存在,這樣在事務提交或者回滾的時候才能夠在每個節(jié)點上保持原子性。在事務執(zhí)行過程中,有可能會更新大量數據(批處理事務),這些更新操作在分布式數據庫中不可能采用等到主節(jié)點執(zhí)行完成,然后再復制到從節(jié)點的方法,這種方法的執(zhí)行性能太差,無法滿足業(yè)務需求。巨杉數據庫的做法是事務中的每個寫操作都會產生一個日志記錄,主節(jié)點會把這些日志記錄復制到從節(jié)點重做,并不會等到事務提交才開始復制重做,然后在事務提交的時候,在復制組內部實現二階段提交算法,保證事務在復制組中的原子性和一致性。
另外,RAFT算法中的命令提交成功條件是:集群中的大部分服務器持有了這條命令的日志記錄。RAFT算法能保證集群是最終一致的,但不保證某個時刻集群是一致的。這種機制在實現集群災備的時候會有問題。例如:在5臺服務器的集群中,3臺在中心A,2臺在中心B,如果領導人在中心A中,那么A中的3臺服務器處于同一個網絡,通常情況下日志復制時間都要比處于遠端中心B的2臺服務器短,也就是說不能保證中心B的服務器中必定持有最新的日志記錄,如果中心A出現災難事故,無法恢復,那么中心B中的服務器的數據是不完整的。這中情況對于某些業(yè)務(銀行賬務)是無法接受的。巨杉數據庫的做法是設置寫副本數參數,強制要求必須有多少個節(jié)點都持有最新日志記錄,才算是復制成功。
所以,巨杉分布式數據庫在節(jié)點選舉的實現中優(yōu)化了RAFT算法,而在數據同步/日志復制則完全開發(fā)了自己的算法。在巨杉分布式數據庫的架構中,主節(jié)點對應了RAFT算法中的領導人,從節(jié)點對應跟隨人,候選人是一樣的;巨杉數據庫的復制日志對應了RAFT算法中的日志記錄;巨杉數據庫的復制組對應了一個RAFT算法中的一組服務器。巨杉數據庫在一個集群里面支持多個復制組,每個復制組都可以看作是一組RAFT算法的服務器。
巨杉分布式數據庫的節(jié)點類型分為:協(xié)調節(jié)點,編目節(jié)點,數據節(jié)點。其中,多個協(xié)調節(jié)點的任務是接收命令,并分發(fā)命令到編目節(jié)點和數據節(jié)點,本身不保存數據,相互之間也沒有關系,所以不需要考慮可用性問題。編目節(jié)點其實就是一種特殊的數據節(jié)點,其高可用性是和數據節(jié)點一樣的。協(xié)調節(jié)點可以看作是數據節(jié)點復制組的客戶端。
巨杉分布式數據庫也是通過解決3個小問題,從而實現了集群數據一致性這個大問題的。
3.2.1 節(jié)點選舉
巨杉數據庫的復制組可以包含1個到7個數據節(jié)點,但是如果要提供高可用特性復制組的節(jié)點數量必須大于等于3。每個復制組在同一時間只會有一個主節(jié)點,其它的都是從節(jié)點,如果處于選主階段,每個從節(jié)點都可以是候選節(jié)點。巨杉數據庫選主也是采用同組節(jié)點投票的方式,獲得半數以上選票的節(jié)點成為主節(jié)點。
為了保證選主成功并且選出的主節(jié)點包含了最新的數據庫日志,巨杉數據庫在RAFT算法的基礎上做了一些優(yōu)化,特別是在候選節(jié)點的資格選擇上。
從節(jié)點要成為候選節(jié)點并發(fā)起選舉請求必須具有的條件是:自己不是主節(jié)點,剩下能與自己心跳通訊的節(jié)點數量必須大于半數以上,自己的LSN(日志序列號)比其它節(jié)點的LSN新。復制組在主節(jié)點存在的情況下不能自動發(fā)起選舉請求(可以采用手工發(fā)起的方式切換主節(jié)點),只有當主節(jié)點不可用的情況下,從節(jié)點才可以發(fā)起選主請求。如果是集群分裂的情況,比如5個節(jié)點由于網絡原因分裂為相互不通的2節(jié)點集群和3節(jié)點集群,如果當前主節(jié)點在3節(jié)點的集群中,那么由于此集群的節(jié)點存活數大于半數,不會發(fā)生選主,如果當前主節(jié)點在2節(jié)點的集群中,那么主節(jié)點將自動降為從節(jié)點,并且3節(jié)點的集群將發(fā)起選主請求,重新選擇一個主節(jié)點。
在復制組所有節(jié)點正常的時候,每個節(jié)點都會通過共享心跳信息sharing-beat共享狀態(tài)信息。共享心跳信息包括:心跳 ID、自身開始LSN、自身終止LSN、時間戳、數據組版本號、自身當前的角色和同步狀態(tài)。如圖所示:

每個節(jié)點都維護一張 status-sharing table 表,用來記錄節(jié)點狀態(tài)。sharing-beat 每2秒發(fā)送一次,采集應答信息,若連續(xù)兩次未收到應答信息,則認為節(jié)點宕機。節(jié)點進程中的ReplReader(復制監(jiān)聽線程)負責節(jié)點狀態(tài)信息的接收和發(fā)送。
從節(jié)點發(fā)起選主之前,會檢查共享心跳信息中本節(jié)點的LSN以及其它從節(jié)點的LSN,如果自己LSN大于等于其它從節(jié)點的LSN,就可以發(fā)起選主請求,否則就不發(fā)起。
在選主中,如果多個候選從節(jié)點的LSN相同,并且都發(fā)起了請求,那么將比較各從節(jié)點的權重配置參數(weight)。復制組的每個節(jié)點都可單獨配置不同的權重,從0到100,數字越大權重越高,相同LSN的從節(jié)點,權重高的選主成功。
如果多個從節(jié)點的LSN相同,權重配置也相同,那么將比較這些從節(jié)點的節(jié)點號,在創(chuàng)建節(jié)點的時候,每個節(jié)點的節(jié)點號是不同的,節(jié)點號大的將選主成功。
從上面可以看出巨杉分布式數據庫在選主中,優(yōu)化了選主流程,在RAFT算法的基礎上增加了權重和節(jié)點號的判斷,這樣就不會出現RAFT算法中多個節(jié)點選主票數相同導致失敗的情況。
下面舉一個簡單例子,描述一下巨杉數據庫的選主流程。
如圖所示,一個3節(jié)點的復制組,包括:主節(jié)點A,從節(jié)點B,從節(jié)點C。在正常情況下,三個節(jié)點通過心跳共享狀態(tài)信息。如果主節(jié)點A由于某種原因故障(服務器掉電/網絡故障/磁盤故障等等)將自動降為從節(jié)點,集群開始重新選主。

兩個從節(jié)點,發(fā)現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,我的權重是80,還是我當?”
從節(jié)點C:“B兄不好意思,我的權重也是80,我也想當。我的節(jié)點號是1008。”
從節(jié)點B:“C兄的節(jié)點號是1008,我的是1006;輸了輸了,C兄你是老大了。”
從節(jié)點C:“我自己投了自己一票,B兄投了我一篇,現在是2票,大于3/2+1,嗯夠了。嗨B兄我是老大了。”
從節(jié)點B:“收到,老大。”
重新選主成功后,新主節(jié)點會通知編目節(jié)點變更主節(jié)點信息;協(xié)調節(jié)點會從編目節(jié)點同步節(jié)點狀態(tài)信息,并連接到新主節(jié)點;協(xié)調節(jié)點也可以通過遍歷節(jié)點的方式來獲得新主節(jié)點信息。這樣就在主節(jié)點宕機后實現了高可用能力。原主節(jié)點A恢復后,自動成為從節(jié)點。
3.2.2 日志復制
巨杉數據庫的日志復制機制與RAFT的日志復制機制不同。首先,RAFT算法的日志總是從領導人(Leader)發(fā)送給追隨者(Follower),追隨者之間不會交換日志數據;而巨杉數據庫的日志復制在源節(jié)點(發(fā)送日志的節(jié)點)和目標節(jié)點(請求日志的節(jié)點)之間進行,并且是目標節(jié)點主動向源節(jié)點請求日志數據,源節(jié)點大多數情況是主節(jié)點,但其它從節(jié)點也可以是源節(jié)點,目標節(jié)點只能是從節(jié)點。其次,RAFT算法中如果領導人沒有追隨者的日志復制返回信息,領導人會持續(xù)的給這個追隨者發(fā)送日志直到收到返回信息,都是增量復制;而巨杉數據庫的數據同步復制可以是日志增量復制,也可能觸發(fā)數據全量同步。
巨杉數據庫的日志復制不采用RAFT算法是因為其在分布式數據庫的場景中并不適合。例如,如果某個從節(jié)點宕機,而按照RAFT算法主節(jié)點持續(xù)的向此從節(jié)點發(fā)送日志信息,而日志數據又很大,那么就會占用主節(jié)點大量的CPU/內存/網絡資源,嚴重的影響主節(jié)點的性能,有可能造成阻塞;巨杉數據庫采用從節(jié)點請求的方式,只有從節(jié)點是正常狀態(tài)的時候才會請求新的日志數據,并清楚的給出需要哪些日志數據,不會造成重復發(fā)送問題,并且從節(jié)點可以作為源節(jié)點以可以大大減少主節(jié)點的工作負載。另外,由于實際環(huán)境中,存儲空間是有限的,數據庫能夠配置的日志空間也是有限的,所以巨杉數據庫的數據同步模式分為日志增量同步和數據全量同步兩種方式。如果目標節(jié)點需要同步的數據都包含在源節(jié)點的復制日志空間中,就進行日志增量同步;如果數據已經不在復制日志空間中,那么需要進行全量同步。最重要的是,分布式數據庫要求支持ACID及事務的能力,其場景比RAFT算法描述的日志復制場景更復雜,巨杉數據庫采用兩階段提交的算法在兼顧性能和事務一致性的情況下支持復制組內部的事務能力。
日志增量同步模式
在數據節(jié)點和編目節(jié)點中,任何數據增刪改操作均會寫入日志。SequoiaDB 會首先將日志寫入日志緩沖區(qū),然后將其異步寫入本地磁盤。
每個數據復制會在兩個節(jié)點間進行:
源節(jié)點: 為包含新數據的節(jié)點。主節(jié)點并不一定永遠是復制的源節(jié)點。
目標節(jié)點: 為請求進行數據復制的節(jié)點。
復制過程中,目標節(jié)點選擇一個與其最接近的節(jié)點(在共享的節(jié)點狀態(tài)表中,包含了每個節(jié)點的開始LSN和結束LSN可用計算哪個與自己最接近),然后向其發(fā)送一個復制請求。源節(jié)點接到復制請求后,會將目標節(jié)點請求的同步點之后的日志記錄打包并發(fā)送給目標節(jié)點,目標節(jié)點接收到數據包后會重新處理日志中的所有操作。
節(jié)點之間的復制有兩個狀態(tài):
對等狀態(tài)(PEER):當目標節(jié)點請求的日志依然存在于源節(jié)點的日志緩沖區(qū)中,兩節(jié)點之間為對等狀態(tài)
遠程追趕狀態(tài)(RemoteCatchup):當目標節(jié)點請求的日志不存在于源節(jié)點的日志緩沖區(qū)中,但依然存在于源節(jié)點的日志文件中,兩節(jié)點之間為遠程追趕狀態(tài)
如果目標節(jié)點請求的日志已經不再存在于源節(jié)點的日志文件中,目標節(jié)點則進入全量同步狀態(tài)。
當兩節(jié)點處于對等狀態(tài)時,同步請求在源節(jié)點可以直接從內存中獲取數據,因此目標節(jié)點選擇復制源節(jié)點時,總會嘗試選擇距離自己當前日志點最近的數據節(jié)點,使其所包含的日志盡量坐落在內存中。
數據全量同步
在分區(qū)組內,當一個新的節(jié)點加入分區(qū)組,或者故障節(jié)點重新加入分區(qū)組(故障節(jié)點日志版本與其它節(jié)點相差過大,超過了節(jié)點事務日志空間的大小;或者重啟發(fā)現故障節(jié)點的數據不一致),需要進行數據全量同步,以保障新的節(jié)點與現有節(jié)點之間數據的一致性。
在進行數據全量同步時有兩個節(jié)點參與:
源節(jié)點: 為包含有效數據的節(jié)點。主節(jié)點并不一定永遠是同步的源節(jié)點。任何與主節(jié)點處于同步狀態(tài)的從節(jié)點均可作為源節(jié)點進行數據同步。
目標節(jié)點: 為新加入組,或重新入組的故障節(jié)點。同步時該節(jié)點下原有的數據會被廢棄。
全量同步發(fā)生時,目標節(jié)點會定期向源節(jié)點請求數據。源節(jié)點將數據打包后作為大數據塊發(fā)送給目標節(jié)點。當目標節(jié)點重做該數據塊內所有數據后,向源節(jié)點請求新的數據塊。
為保障源節(jié)點在同步時可進行寫操作,所有已經被發(fā)送給目標節(jié)點的數據頁如果被更改,其更新會被同步到目標節(jié)點,以保障全量同步過程中更新的數據不會損失。
同步副本數
巨杉數據庫在實現數據同步的時候,為了適應不同的業(yè)務場景,可以為每個集合單獨設置ReplSize(寫操作同步副本數)參數。
ReplSize默認值為1。其可選取值如下:
-1:表示寫請求需同步到該復制組若干活躍的節(jié)點之后,數據庫寫操作才返回應答給客戶端。
0:表示寫請求需同步到該復制組的所有節(jié)點之后,數據庫寫操作才返回應答給客戶端。
1 - 7:表示寫請求需同步到該復制組指定數量個節(jié)點之后,數據庫寫操作才返回應答給客戶端。
在實際項目中,為了保證數據不丟失,需要把ReplSize設置為大于1,或者-1。例如,如果一個集合的ReplSize設置為2,那么主節(jié)點寫操作必須等到有一個從節(jié)點返回成功才會給協(xié)調節(jié)點返回成功,這樣能夠保證如果此時主節(jié)點宕機,至少有一個從節(jié)點已經持有了成功的日志數據,在重新選主時,這個從節(jié)點根據LSN最新規(guī)則,必然成為候選者,從而保證數據不丟失。
3.3 安全性
巨杉數據庫的集群一致性算法為了保證數據不錯不丟,保證數據的安全性,也對選舉規(guī)則和復制規(guī)則做了一些限制條件。
選舉限制
前面也提到,在巨杉數據庫中節(jié)點想要成為候選節(jié)點并發(fā)起選主請求,必須具備的條件是:自己不是主節(jié)點,剩下能與自己心跳通訊的節(jié)點數量必須大于半數以上,自己的LSN(日志序列號)比其它節(jié)點的LSN新。這些規(guī)則保證了,新主節(jié)點的數據是最新的,而且能夠與大于半數以上的其它節(jié)點通訊。
日志復制限制
巨杉數據庫在復制組內部采用兩階段提交的算法支持事務能力,并使用表的配置參數ReplSize(寫副本數)強制主節(jié)點必須同步成功多少個從節(jié)點。通過這些手段,巨杉數據庫可以保證復制組內部節(jié)點的數據和事務的一致性/完整性。
在日志復制方面,復制組的主節(jié)點將保證每一個日志(包含一個唯一并遞增的LSN)都能夠按照日志復制的規(guī)則復制到從節(jié)點上。例如,如果一張表的ReplSize參數設置為2,主節(jié)點保證至少在收到一個從節(jié)點的日志復制完成的確認后才會返回成功給協(xié)調節(jié)點,否則返回失敗;如果ReplSize設置為-1,主節(jié)點將在收到所有活動從節(jié)點的日志復制成功的確認后才會返回成功給協(xié)調節(jié)點,否則返回失敗。
在事務完整性方面,巨杉數據庫在復制組內的兩階段提交事務實現流程如下:
客戶端使用transBegin()開始事務,并發(fā)送給協(xié)調節(jié)點,協(xié)調節(jié)點再發(fā)送給主節(jié)點執(zhí)行,主節(jié)點將生成一個唯一的事務ID。
在主節(jié)點接收到第一個寫操作后(如insert,update,delete),會產生一條日志記錄(日志記錄中包含了事務ID)。這條日志記錄將根據規(guī)則(復制副本數,即使是ReplSize設置為1,巨杉數據庫在執(zhí)行事務的時候都必須保證有一個從節(jié)點持有了事務ID的日志記錄)發(fā)送給其它從節(jié)點并確認成功。
主節(jié)點將繼續(xù)完成其它操作,任何寫操作都將產生一條新的日志記錄,并根據復制規(guī)則發(fā)送給其它從節(jié)點并確認成功。
主節(jié)點收到transCommit()指令后,將開始二階段提交。
主節(jié)點首先執(zhí)行第一階段,預提交(pre-commit)。在此階段將產生一條預提交日志記錄,并發(fā)送給從節(jié)點并確保從節(jié)點確認收到。
然后主節(jié)點執(zhí)行第二階段,真正提交(Snd-Commit)。在此階段會產生一條提交日志記錄,并發(fā)送給從節(jié)點執(zhí)行并確保從節(jié)點成功收到。當這個階段成功后,整個事務才確認成功,并返回給協(xié)調節(jié)點成功。
在整個事務過程中,如果有任何違反復制同步規(guī)則的情況發(fā)生,導致事務無法進行下去(例如:在執(zhí)行插入數據的時候,數據所在的表的ReplSize是3,而由于某種原因復制組包括主節(jié)點在內只有2給活動節(jié)點,那么插入操作將失敗,導數事務無法繼續(xù)進行),那么將進行事務回滾,把之前已經執(zhí)行的操作復原。
在事務過程中如果出現主節(jié)點宕機等情況,巨杉數據庫將根據事務執(zhí)行的情況在新的主節(jié)點選舉成功后自動判斷是繼續(xù)提交事務還是回滾事務,解決可疑事務問題。
關于 SequoiaDB高可用的原理是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)-成都網站建設公司行業(yè)資訊頻道了解更多相關知識。
新聞標題:SequoiaDB高可用的原理是什么-創(chuàng)新互聯(lián)
網頁路徑:http://chinadenli.net/article36/dpgspg.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、電子商務、做網站、網頁設計公司、網站設計、軟件開發(fā)
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)