3.数据的一致性与一致性算法(CAP原则、Paxos算法、Raft算法、ZAB协议)
數(shù)據(jù)的一致性與一致性算法(CAP原則、Paxos算法、Raft算法、ZAB協(xié)議)
一、數(shù)據(jù)的一致性
1.定義
- 一些分布式系統(tǒng)通過復(fù)制數(shù)據(jù)來提高系統(tǒng)的可靠性和容錯性,并且將數(shù)據(jù)的不同的副本存放在不同的機(jī)器
- 在數(shù)據(jù)有多分副本的情況下,如果網(wǎng)絡(luò)、服務(wù)器或者軟件出現(xiàn)故障,會導(dǎo)致部分副本寫入成功,部分副本寫入失敗。這就造成各個副本之間的數(shù)據(jù)不一致,數(shù)據(jù)內(nèi)容沖突。
2.模型
- 強(qiáng)一致性
- 要求無論更新操作實(shí)在哪一個副本執(zhí)行,之后所有的讀操作都要能獲得最新的數(shù)據(jù)。
- 弱一致性
- 用戶讀到某一操作對系統(tǒng)特定數(shù)據(jù)的更新需要一段時間,我們稱這段時間為“不一致性窗口”。
- 最終一致性
- 是弱一致性的一種特例,保證用戶最終能夠讀取到某操作對系統(tǒng)特定數(shù)據(jù)的更新。
- 從客戶端來看,有可能暫時獲取的不是最新的數(shù)據(jù),但是最終還是能訪問到最新的
- 從服務(wù)端來看,數(shù)據(jù)存儲并復(fù)制到分布到整個系統(tǒng)超過半數(shù)的節(jié)點(diǎn),以保證數(shù)據(jù)最終一致。
3.最終一致性
-
因果一致性(Casual Consistency)
- 如果進(jìn)程A通知進(jìn)程B它已更新了一個數(shù)據(jù)項(xiàng),那么進(jìn)程B的后續(xù)訪問將返回更新后的值,且一次寫入將保證取代前一次寫入。
- 與進(jìn)程A無因果關(guān)系的進(jìn)程C的訪問,遵守一般的最終一致性規(guī)則。
- 查詢微博和評論
-
讀己之所寫一致性(read-your-writes)
- 當(dāng)進(jìn)程A自己更新一個數(shù)據(jù)項(xiàng)之后,它總是訪問到更新過的值,絕不會看到舊值。這是因果一致性模型的一個特例。
- 讀自己的數(shù)據(jù)都從主服務(wù)器去讀取,讀其他人的數(shù)據(jù)再從從服務(wù)器去讀取
- 發(fā)表微博與修改微博
-
會話(Session)一致性
- 這是上一個模型的實(shí)用版本,它把訪問存儲系統(tǒng)的進(jìn)程放到會話的上下文中。只要會話還存
- 在,系統(tǒng)就保證“讀己之所寫”一致性。如果由于某些失敗情形令會話終止,就要建立新的會話,而且系統(tǒng)的保證不會延續(xù)到新的會話。
- 確保會話內(nèi)訪問的都是最新的
-
單調(diào)(Monotonic)讀一致性
- 如果進(jìn)程已經(jīng)看到過數(shù)據(jù)對象的某個最新值,那么任何后續(xù)訪問都不會返回在那個值之前的值。
- 不會讀取最舊的數(shù)據(jù)
-
單調(diào)寫一致性
-
系統(tǒng)保證來自同一個進(jìn)程的寫操作順序執(zhí)行。要是系統(tǒng)不能保證這種程度的一致性,就非常難以編程了。
-
按照順序完成數(shù)據(jù)的書寫
-
二、CAP原則
1.定義
- CAP定理是2000年,由 Eric Brewer 提出來的。Brewer認(rèn)為在分布式的環(huán)境下設(shè)計和部署系統(tǒng)時,有3個核心的需求,以一種特殊的關(guān)系存在。
- 這3個核心的需求是:Consistency,Availability和Partition Tolerance
- CAP定理認(rèn)為:一個提供數(shù)據(jù)服務(wù)的存儲系統(tǒng)無法同時滿足數(shù)據(jù)一致性、數(shù)據(jù)可用性、分區(qū)容忍性
2.概念
- Consistency:
- 一致性,這個和數(shù)據(jù)庫ACID的一致性類似,但這里關(guān)注的所有數(shù)據(jù)節(jié)點(diǎn)上的數(shù)據(jù)一致性和正確性,而數(shù)據(jù)庫的ACID關(guān)注的是在在一個事務(wù)內(nèi),對數(shù)據(jù)的一些約束。
- 系統(tǒng)在執(zhí)行過某項(xiàng)操作后仍然處于一致的狀態(tài)。在分布式系統(tǒng)中,更新操作執(zhí)行成功后所有的用戶都應(yīng)該讀取到最新值。
- Availability:
- 可用性,每一個操作總是能夠在一定時間內(nèi)返回結(jié)果。需要注意“一定時間”和“返回結(jié)果”。
- “一定時間”是指系統(tǒng)結(jié)果必須在給定時間內(nèi)返回。
- “返回結(jié)果”是指系統(tǒng)返回操作成功或失敗的結(jié)果。
- Partition Tolerance:
- 分區(qū)容忍性,是否可以對數(shù)據(jù)進(jìn)行分區(qū)。這是考慮到性能和可伸縮性。
3.推導(dǎo)
- 如果要求對數(shù)據(jù)進(jìn)行分區(qū)了,就說明了必須節(jié)點(diǎn)之間必須進(jìn)行通信,涉及到通信,就無法確保在有限的時間內(nèi)完成指定的任務(wù)
- 如果要求兩個操作之間要完整的進(jìn)行,因?yàn)樯婕暗酵ㄐ?#xff0c;肯定存在某一個時刻只完成一部分的業(yè)務(wù)操作,在通信完成的這一段時間內(nèi),數(shù)據(jù)就是不一致性的。
- 如果要求保證一致性,那么就必須在通信完成這一段時間內(nèi)保護(hù)數(shù)據(jù),使得任何訪問這些數(shù)據(jù)的操作不可用。
4.結(jié)論
- 在大型網(wǎng)站應(yīng)用中,數(shù)據(jù)規(guī)模總是快速擴(kuò)張的,因此可伸縮性即分區(qū)容忍性必不可少,規(guī)模變大以后,機(jī)器數(shù)量也會變得龐大,這是網(wǎng)絡(luò)和服務(wù)器故障會頻繁出現(xiàn),要想保證應(yīng)用可用,就必須保證分布式處理系統(tǒng)的高可用性。
- 在大型網(wǎng)站中,通常會選擇強(qiáng)化分布式存儲系統(tǒng)的可用性和伸縮性,在某種程度上放棄一致性。
三、Paxos算法
1.簡介
- Paxos算法是Leslie Lamport宗師提出的一種基于消息傳遞的分布式一致性算法,使其獲得2013年圖靈獎。
- Paxos在1990年提出,被廣泛應(yīng)用于分布式計算中,Google的Chubby,Apache的Zookeeper都是基于它的理論來實(shí)現(xiàn)的
- Paxos算法解決的問題是分布式一致性問題,即一個分布式系統(tǒng)中的各個進(jìn)程如何就某個值(決議)達(dá)成一致。
- 傳統(tǒng)節(jié)點(diǎn)間通信存在著兩種通訊模型:共享內(nèi)存(Shared memory)、消息傳遞(Messagespassing),Paxos是一個基于消息傳遞的一致性算法。
2.算法描述
Paxos描述了這樣一個場景,有一個叫做Paxos的小島(Island)上面住了一批居民,島上面所有的事情 由一些特殊的人決定,他們叫做議員(Senator)。議員的總數(shù)(Senator Count)是確定的,不能更 改。島上每次環(huán)境事務(wù)的變更都需要通過一個提議(Proposal),每個提議都有一個編號(PID),這個編 號是一直增長的,不能倒退。每個提議都需要超過半數(shù)((Senator Count)/2 +1)的議員同意才能生 效。每個議員只會同意大于當(dāng)前編號的提議,包括已生效的和未生效的。如果議員收到小于等于當(dāng)前編號 的提議,他會拒絕,并告知對方:你的提議已經(jīng)有人提過了。這里的當(dāng)前編號是每個議員在自己記事本上 面記錄的編號,他不斷更新這個編號。整個議會不能保證所有議員記事本上的編號總是相同的。現(xiàn)在議會 有一個目標(biāo):保證所有的議員對于提議都能達(dá)成一致的看法。 現(xiàn)在議會開始運(yùn)作,所有議員一開始記事本上面記錄的編號都是0。有一個議員發(fā)了一個提議:將電費(fèi)設(shè) 定為1元/度。他首先看了一下記事本,嗯,當(dāng)前提議編號是0,那么我的這個提議的編號就是1,于是他 給所有議員發(fā)消息:1號提議,設(shè)定電費(fèi)1元/度。其他議員收到消息以后查了一下記事本,哦,當(dāng)前提議 編號是0,這個提議可接受,于是他記錄下這個提議并回復(fù):我接受你的1號提議,同時他在記事本上記 錄:當(dāng)前提議編號為1。發(fā)起提議的議員收到了超過半數(shù)的回復(fù),立即給所有人發(fā)通知:1號提議生效!收 到的議員會修改他的記事本,將1好提議由記錄改成正式的法令,當(dāng)有人問他電費(fèi)為多少時,他會查看法 令并告訴對方:1元/度。 現(xiàn)在看沖突的解決:假設(shè)總共有三個議員S1-S3,S1和S2同時發(fā)起了一個提議:1號提議,設(shè)定電費(fèi)。S1 想設(shè)為1元/度, S2想設(shè)為2元/度。結(jié)果S3先收到了S1的提議,于是他做了和前面同樣的操作。緊接著他 又收到了S2的提議,結(jié)果他一查記事本,咦,這個提議的編號小于等于我的當(dāng)前編號1,于是他拒絕了這 個提議:對不起,這個提議先前提過了。于是S2的提議被拒絕,S1正式發(fā)布了提議: 1號提議生效。S2 向S1或者S3打聽并更新了1號法令的內(nèi)容,然后他可以選擇繼續(xù)發(fā)起2號提議。3.Paxos推斷
- 小島(Island) 服務(wù)器集群
- 議員(Senator) 單臺服務(wù)器
- 議員的總數(shù)(Senator Count)是確定的
- 提議(Proposal) 每一次對集群中的數(shù)據(jù)進(jìn)行修改
- 每個提議都有一個編號(PID),這個編號是一直增長的
- 每個提議都需要超過半數(shù)((Senator Count)/2 +1)的議員同意才能生效
- 每個議員只會同意大于當(dāng)前編號的提議
- 每個議員在自己記事本上面記錄的編號,他不斷更新這個編號
- 整個議會不能保證所有議員記事本上的編號總是相同的
- 議會有一個目標(biāo):保證所有的議員對于提議都能達(dá)成一致的看法。
- 前期投票(>1/2),后期廣播(all)
- Paxos算法
- 數(shù)據(jù)的全量備份
- 弱一致性 ——》最終一致性
4.算法模型延伸
如果Paxos島上的議員人人平等,在某種情況下會由于提議的沖突而產(chǎn)生一個“活鎖”(所謂活鎖我的理解是大 家都沒有死,都在動,但是一直解決不了沖突問題)。Paxos的作者在所有議員中設(shè)立一個總統(tǒng),只有總統(tǒng)有 權(quán)發(fā)出提議,如果議員有自己的提議,必須發(fā)給總統(tǒng)并由總統(tǒng)來提出。 情況一:屁民甲(Client)到某個議員(ZK Server)那里詢問(Get)某條法令的情況(ZNode的數(shù)據(jù)),議員毫 不猶豫的拿出他的記事本(local storage),查閱法令并告訴他結(jié)果,同時聲明:我的數(shù)據(jù)不一定是最新 的。你想要最新的數(shù)據(jù)?沒問題,等著,等我找總統(tǒng)Sync一下再告訴你。 情況二:屁民乙(Client)到某個議員(ZK Server)那里要求政府歸還欠他的一萬元錢,議員讓他在辦公室等 著,自己將問題反映給了總統(tǒng),總統(tǒng)詢問所有議員的意見,多數(shù)議員表示欠屁民的錢一定要還,于是總統(tǒng)發(fā)表 聲明,從國庫中拿出一萬元還債,國庫總資產(chǎn)由100萬變成99萬。屁民乙拿到錢回去了(Client函數(shù)返回)。 情況三:總統(tǒng)突然掛了,議員接二連三的發(fā)現(xiàn)聯(lián)系不上總統(tǒng),于是各自發(fā)表聲明,推選新的總統(tǒng),總統(tǒng)大選期 間政府停業(yè),拒絕屁民的請求。- 無主集群模型
- 人人都會發(fā)送指令,投票
- 投票人數(shù)有可能導(dǎo)致分區(qū)(分不同陣營),
- 6個節(jié)點(diǎn) 33對立
- 類似于以前黨爭
- 投票人數(shù)有可能導(dǎo)致分區(qū)(分不同陣營),
- 事務(wù)編號混亂,每個節(jié)點(diǎn)都有可能有自己的提議
- 提議的編號不能重復(fù)和小于
- 人人都會發(fā)送指令,投票
- 有主集群模型
- 只能有一個主發(fā)送指令,發(fā)送提議
- 單主會單點(diǎn)故障,肯定有備用的方案
- 重新選舉
- 切換到備用節(jié)點(diǎn)
- 如果存在多個主就會腦裂
- 主要集群中節(jié)點(diǎn)數(shù)目高于1/2+1,集群就可以正常運(yùn)行
四、Raft算法
1.簡介
- Raft 適用于一個管理日志一致性的協(xié)議,相比于 Paxos 協(xié)議 Raft 更易于理解和去實(shí)現(xiàn)它。
- Raft 將一致性算法分為了幾個部分,包括領(lǐng)導(dǎo)選取(leader selection)、日志復(fù)制(logreplication)、安全(safety)
- http://thesecretlivesofdata.com/raft/
2.問題
-
分布式存儲系統(tǒng)通過維護(hù)多個副本來提高系統(tǒng)的availability,難點(diǎn)在于分布式存儲系統(tǒng)的核心問題:
- 維護(hù)多個副本的一致性
-
Raft協(xié)議基于復(fù)制狀態(tài)機(jī)(replicated state machine)
-
一組server從相同的初始狀態(tài)起,按相同的順序執(zhí)行相同的命令,最終會達(dá)到一致的狀態(tài)
-
一組server記錄相同的操作日志,并以相同的順序應(yīng)用到狀態(tài)機(jī)。
-
-
Raft有一個明確的場景,就是管理復(fù)制日志的一致性
- 每臺機(jī)器保存一份日志,日志來自于客戶端的請求,包含一系列的命令,狀態(tài)機(jī)會按順序執(zhí)行這些命令。
3.角色分配
- Raft算法將Server劃分為3種狀態(tài),或者也可以稱作角色:
- Leader
- 負(fù)責(zé)Client交互和log復(fù)制,同一時刻系統(tǒng)中最多存在1個。
- Follower
- 被動響應(yīng)請求RPC,從不主動發(fā)起請求RPC。
- Candidate
- 一種臨時的角色,只存在于leader的選舉階段,某個節(jié)點(diǎn)想要變成leader,那么就發(fā)起
- 投票請求,同時自己變成candidate
- Leader
4.算法流程
-
Term
- Term的概念類比中國歷史上的朝代更替,Raft 算法將時間劃分成為任意不同長度的任期(term)。
- 任期用連續(xù)的數(shù)字進(jìn)行表示。每一個任期的開始都是一次選舉(election),一個或多個候選人會試圖成為領(lǐng)導(dǎo)人。如果一個候選人贏得了選舉,它就會在該任期的剩余時間擔(dān)任領(lǐng)導(dǎo)人。在某些情況下,選票會被瓜分,有可能沒有選出領(lǐng)導(dǎo)人,那么,將會開始另一個任期,并且立刻開始下一次選舉。Raft 算法保證在給定的一個任期最多只有一個領(lǐng)導(dǎo)人。
-
RPC
-
Raft 算法中服務(wù)器節(jié)點(diǎn)之間通信使用遠(yuǎn)程過程調(diào)用(RPCs)
-
基本的一致性算法只需要兩種類型的 RPCs,為了在服務(wù)器之間傳輸快照增加了第三種 RPC。
-
RequestVote RPC:候選人在選舉期間發(fā)起
-
AppendEntries RPC:領(lǐng)導(dǎo)人發(fā)起的一種心跳機(jī)制,復(fù)制日志也在該命令中完成
-
InstallSnapshot RPC: 領(lǐng)導(dǎo)者使用該RPC來發(fā)送快照給太落后的追隨者
-
-
-
日志復(fù)制(Log Replication)
-
主要用于保證節(jié)點(diǎn)的一致性,這階段所做的操作也是為了保證一致性與高可用性。
-
當(dāng)Leader選舉出來后便開始負(fù)責(zé)客戶端的請求,所有事務(wù)(更新操作)請求都必須先經(jīng)過Leader處理
-
日志復(fù)制(Log Replication)就是為了保證執(zhí)行相同的操作序列所做的工作。
-
在Raft中當(dāng)接收到客戶端的日志(事務(wù)請求)后先把該日志追加到本地的Log中
-
然后通過heartbeat把該Entry同步給其他Follower,Follower接收到日志后記錄日志然后向Leader發(fā)送ACK
-
當(dāng)Leader收到大多數(shù)(n/2+1)Follower的ACK信息后將該日志設(shè)置為已提交并追加到本地磁盤中
-
通知客戶端并在下個heartbeat中Leader將通知所有的Follower將該日志存儲在自己的本地磁盤中。
-
五、ZAB協(xié)議
1.簡介
- ZAB(Zookeeper Atomic Broadcast) 協(xié)議是為分布式協(xié)調(diào)服務(wù)zookeeper專門設(shè)計的一種支持崩潰恢復(fù)的原子廣播協(xié)議。
- ZAB是ZooKeeper實(shí)現(xiàn)分布式數(shù)據(jù)一致性的核心算法,ZAB借鑒Paxos算法
- 在zookeeper中,主要依賴ZAB協(xié)議來實(shí)現(xiàn)分布式數(shù)據(jù)一致性,基于該協(xié)議,zookeeper實(shí)現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各個副本之間的數(shù)據(jù)一致性。
2.ZAB協(xié)議的三個階段
- 發(fā)現(xiàn):即要求zookeeper集群必須選擇出一個leader進(jìn)程,同時leader會維護(hù)一個follower可用列表。將來客戶端可以這follower中的節(jié)點(diǎn)進(jìn)行通信。
- 同步:leader要負(fù)責(zé)將本身的數(shù)據(jù)與follower完成同步,做到多副本存儲。這樣也是體現(xiàn)了CAP中CP。follower將隊列中未處理完的請求消費(fèi)完成后,寫入本地事物日志中。
- 廣播:leader可以接受客戶端新的proposal請求,將新的proposal請求廣播給所有的follower。
3.協(xié)議核心
- ZAB協(xié)議的核心是定義了對于那些會改變ZooKeeper服務(wù)器數(shù)據(jù)狀態(tài)的事務(wù)請求處理方式,即:
- 所有事務(wù)請求必須由一個全局唯一的服務(wù)器來協(xié)調(diào)處理,這樣的服務(wù)器被稱為Leader服務(wù)器,而余下的其他服務(wù)器稱為Follower服務(wù)器。Leader服務(wù)器負(fù)責(zé)將一個客戶端事務(wù)請求轉(zhuǎn)換成一個事務(wù)Proposal(提議),并將該P(yáng)roposal分發(fā)給集群中所有的Follower服務(wù)器。之后Leader服務(wù)器需要等待所有的Follower服務(wù)器的反饋,一旦超過半數(shù)的Follower服務(wù)器進(jìn)行了正確的反饋后,那么Leader就會再次向所有的Follower服務(wù)器分發(fā)Commit消息,要求其將前一個Proposal進(jìn)提交。
4.兩種基本模式
- 1》崩潰恢復(fù)之?dāng)?shù)據(jù)恢復(fù)
- 當(dāng)整個集群正在啟動時,或者當(dāng)leader節(jié)點(diǎn)出現(xiàn)網(wǎng)絡(luò)中斷、崩潰等情況時,ZAB協(xié)議就會進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的leader,當(dāng)leader服務(wù)器選舉出來后,并且集群中有過半的機(jī)器和該leader節(jié)點(diǎn)完成數(shù)據(jù)同步后(同步指的是數(shù)據(jù)同步,用來保證集群中過半的機(jī)器能夠和leader服務(wù)器的數(shù)據(jù)狀態(tài)保持一致),ZAB協(xié)議就會退出恢復(fù)模式。
- 2》消息廣播之原子廣播
oposal進(jìn)提交。
4.兩種基本模式
- 1》崩潰恢復(fù)之?dāng)?shù)據(jù)恢復(fù)
- 當(dāng)整個集群正在啟動時,或者當(dāng)leader節(jié)點(diǎn)出現(xiàn)網(wǎng)絡(luò)中斷、崩潰等情況時,ZAB協(xié)議就會進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的leader,當(dāng)leader服務(wù)器選舉出來后,并且集群中有過半的機(jī)器和該leader節(jié)點(diǎn)完成數(shù)據(jù)同步后(同步指的是數(shù)據(jù)同步,用來保證集群中過半的機(jī)器能夠和leader服務(wù)器的數(shù)據(jù)狀態(tài)保持一致),ZAB協(xié)議就會退出恢復(fù)模式。
- 2》消息廣播之原子廣播
- 當(dāng)集群中已經(jīng)有過半的Follower節(jié)點(diǎn)完成了和Leader狀態(tài)同步以后,那么整個集群就進(jìn)入了消息廣播模式。這個時候,在Leader節(jié)點(diǎn)正常工作時,啟動一臺新的服務(wù)器加入到集群,那這個服務(wù)器會直接進(jìn)入數(shù)據(jù)恢復(fù)模式,和leader節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步。同步完成后即可正常對外提供非事務(wù)請求的處理。
總結(jié)
以上是生活随笔為你收集整理的3.数据的一致性与一致性算法(CAP原则、Paxos算法、Raft算法、ZAB协议)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 电话拨号器程序
- 下一篇: oracle utl file putf