【RPC】分布式一致性与一致性协议
文章目錄
- 分布式一致性
- 1. 線性一致性
- 2. 順序一致性
- 3. 因果一致性
- 4. 單調(diào)一致性
- 5. 最終一致性
- 一致性協(xié)議
- 1. Paxos算法
- 2. Raft算法
分布式一致性
在CAP、ACID和BASE中都提到了一致性。但是對(duì)于一致性的整個(gè)定義還是非常模糊的,所以本文會(huì)詳細(xì)介紹一致性的模型,以及目前比較流行的一致性協(xié)議。
數(shù)據(jù)一致性并不只有存在與不存在兩種情況,就像可以用0%到100%之間的任意數(shù)值來(lái)代表可用性的程度一樣,一致性也有一些分類(lèi)。一致性模型按照強(qiáng)弱可以粗略地分為弱一致性模型、最終一致性模型和強(qiáng)一致性模型。
- 弱一致性模型的特點(diǎn)是向系統(tǒng)更新或者寫(xiě)入一個(gè)數(shù)值后,后續(xù)的讀操作不一定能夠讀到這個(gè)最新的數(shù)值。
- 最終一致性模型的特點(diǎn)是向系統(tǒng)更新或者寫(xiě)入一個(gè)數(shù)值后,后續(xù)一段時(shí)間內(nèi)的讀操作可能讀取不到這個(gè)最新的值,但在該時(shí)間段過(guò)后,一定能夠讀到最新的數(shù)值。最終一致性模型又可細(xì)分為:因果一致性、單調(diào)一致性和最終一致性。
- 強(qiáng)一致性模型的特點(diǎn)是向系統(tǒng)更新或?qū)懭胍粋€(gè)數(shù)值后,無(wú)論何時(shí)都能夠讀到這個(gè)最新的數(shù)值。強(qiáng)一致性模型又可以細(xì)分為兩類(lèi):線性一致性和順序一致性。
下面就分別介紹一下這幾種一致性模型。
1. 線性一致性
線性一致性又稱(chēng)為原子一致性和強(qiáng)一致性。
Linearizability: A Correctness Condition for Concurrent Objects. Maurice P. Herlihy, Jeannette M. Wing. 1987.
如果需要達(dá)到線性一致性,則需要滿足如下條件:
- 1)任何一次讀操作都可以讀到某個(gè)數(shù)據(jù)的最新值。
- 2)系統(tǒng)中所有的節(jié)點(diǎn)內(nèi)執(zhí)行的時(shí)間順序都和系統(tǒng)級(jí)別時(shí)鐘下看到的時(shí)間順序一致。
第一點(diǎn)非常容易理解,第二點(diǎn)則約束了兩個(gè)維度下時(shí)間的執(zhí)行順序都必須是一樣的。這兩個(gè)維度是指單個(gè)進(jìn)程內(nèi)的時(shí)鐘順序和整個(gè)系統(tǒng)的時(shí)鐘順序。下面通過(guò)一個(gè)例子來(lái)理解一下。
圖中有三個(gè)進(jìn)程P1、P2、P3,從P1進(jìn)程來(lái)看,只是執(zhí)行了一次寫(xiě)操作。從P2和P3進(jìn)程來(lái)看。事件順序都是先執(zhí)行一次寫(xiě)操作,然后執(zhí)行一次讀操作。從整個(gè)系統(tǒng)的時(shí)鐘順序來(lái)看,先執(zhí)行三次寫(xiě)操作,然后執(zhí)行兩次讀操作,所以最近一次的值是3,讀操作讀到的值也就是3。
2. 順序一致性
上面的例子中五個(gè)事件在時(shí)間上沒(méi)有重疊,但是在實(shí)際的場(chǎng)景中,不同進(jìn)程的事件執(zhí)行的時(shí)間點(diǎn)一定會(huì)有重疊,如下面的例子:
這三個(gè)進(jìn)程在執(zhí)行三次寫(xiě)操作和三次讀操作時(shí)的時(shí)間點(diǎn)有重疊,從系統(tǒng)級(jí)時(shí)鐘的維度來(lái)看,整個(gè)事件的執(zhí)行順序應(yīng)該是write1→write2→write3→read2→read3→read2(數(shù)字代表進(jìn)程標(biāo)識(shí))。如果按照線性一致性的約束,則第一次read2讀到的值應(yīng)該是a=3,因?yàn)榈谝淮蝦ead前一次的寫(xiě)操作時(shí)write3。但是圖中的結(jié)果卻是a=2,這是因?yàn)閣rite3操作雖然實(shí)在read2操作之前開(kāi)始執(zhí)行的,但是write3操作結(jié)束的事件卻是在第一次read2操作開(kāi)始之后。從進(jìn)程P2的視角看,事件執(zhí)行順序應(yīng)該時(shí)write2→read2→write3→write1→read2,P2進(jìn)程和系統(tǒng)級(jí)別時(shí)鐘的視角看到的事件執(zhí)行順序是完全不一樣的。而這種時(shí)間點(diǎn)重疊,并且不滿足系統(tǒng)級(jí)別時(shí)鐘的事件執(zhí)行順序的一致性成為順序一致性。
順序一致性的約束如下:
- 1)任何一次讀操作都可以讀到某個(gè)數(shù)據(jù)的最新值,這一點(diǎn)和線性一致性是相同的。
- 2)任何進(jìn)程看到的事件順序是合理的,達(dá)成一致即可,并不需要所有進(jìn)程的時(shí)間順序和系統(tǒng)級(jí)時(shí)鐘下的事件順序一致,它放寬了對(duì)一致性的要求,并不像線性一致性一樣嚴(yán)格。
3. 因果一致性
線性一致性和順序一致性有一個(gè)相同的約束,就是任何一次讀操作都可以讀到某個(gè)數(shù)據(jù)的最新值,這是強(qiáng)一致性的表現(xiàn)。而因果一致性屬于最終一致,它的約束如下:
- 1)對(duì)于具有因果關(guān)系的讀/寫(xiě)事件,所有進(jìn)程看到的事件順序必須一致。
- 2)對(duì)于沒(méi)有因果關(guān)系的讀/寫(xiě)事件,進(jìn)程可以以不同的順序看到這些并發(fā)的事件。
4. 單調(diào)一致性
單調(diào)一致性可以分為單調(diào)讀一致性和單調(diào)寫(xiě)一致性。
單調(diào)讀一致性指的是任何時(shí)刻一旦讀到某個(gè)數(shù)據(jù)項(xiàng)在某次更新后的值,就不會(huì)再讀到比這個(gè)值更舊的值。
單調(diào)寫(xiě)一致性指的是一個(gè)進(jìn)程對(duì)某一個(gè)數(shù)據(jù)項(xiàng)執(zhí)行的寫(xiě)操作必須在該進(jìn)程對(duì)數(shù)據(jù)項(xiàng)執(zhí)行任何后續(xù)寫(xiě)操作之前完成。
相較于因果一致性,單調(diào)一致性更聚焦于單個(gè)進(jìn)程內(nèi)的讀/寫(xiě)操作順序。
5. 最終一致性
因果一致性和單調(diào)一致性都屬于最終一致性中的一種,只是在最終一致性的基礎(chǔ)上增加了一致性的強(qiáng)度,因果一致性是在最終一致性的基礎(chǔ)上增加了因果關(guān)系的約束,單調(diào)一致性是在最終一致性的基礎(chǔ)上增加了單進(jìn)程內(nèi)的約束。而沒(méi)有增加其他約束的最終一致性也就是字面上的最終一致性的意思,只有一個(gè)約束,就是向系統(tǒng)寫(xiě)入更新或者寫(xiě)入一個(gè)數(shù)值,后續(xù)一段時(shí)間內(nèi)的讀操作可能讀取不到這個(gè)最新的值,但是在該時(shí)間段過(guò)后,一定能夠讀到這個(gè)最新的數(shù)值。
對(duì)比以上幾個(gè)一致性模型的約束條件,可以發(fā)現(xiàn)它們之間也有一定的強(qiáng)弱之分,由弱到強(qiáng),分別是最終一致性、單調(diào)一致性、因果一致性、順序一致性、線性一致性。
一致性模型是理論總結(jié),一致性協(xié)議則是一致性模型的具體表現(xiàn)形式。與之經(jīng)常混淆的是共識(shí)算法。共識(shí)和一致性描述的內(nèi)容并不相同,共識(shí)用來(lái)描述一組進(jìn)程間的協(xié)作過(guò)程,并且確定下一個(gè)操作,而一致性描述的是進(jìn)程間某一時(shí)刻的狀態(tài)。共識(shí)和一致性相比,共識(shí)的概念更狹隘一些,因?yàn)檫_(dá)成共識(shí)就可以達(dá)到一致性。但是需要達(dá)到一致性,并不一定需要達(dá)成共識(shí),而一致性有強(qiáng)弱之分,共識(shí)算法是一致性協(xié)議的一種具體實(shí)現(xiàn)手段。
一致性協(xié)議
1. Paxos算法
Paxos是一種基于消息傳遞且具有高度容錯(cuò)特性的共識(shí)算法。
在分布式系統(tǒng)中,只能減少卻無(wú)法避免進(jìn)程掛掉、進(jìn)程重啟、通信消息丟失、延遲等情況,Paxos算法實(shí)現(xiàn)的就是在發(fā)生這些異常時(shí),不會(huì)破壞分布式系統(tǒng)決議的一致性。一些進(jìn)程可以提出各種請(qǐng)求,最終只有一個(gè)請(qǐng)求會(huì)被選中,只要有一個(gè)請(qǐng)求被選中,那么其他進(jìn)程都能獲得該請(qǐng)求帶來(lái)的變化。
在Paxos算法中有三類(lèi)角色,分別是
- Acceptor(決策者):用于決策最終選用哪個(gè)決議。
- Proposer(提議者):該角色的職責(zé)為向決策者提出提議。
- Learner(最終決策執(zhí)行者):該角色的職責(zé)是執(zhí)行最終選定的提議。
從提議的提出到提議的選定,再到提議的執(zhí)行,可以大致分為兩個(gè)階段,第一個(gè)階段就是決策者選出一個(gè)最終的提議(其實(shí)是Proposer與Acceptor之間的交互),第二階段就是最終決策執(zhí)行者如何獲取并執(zhí)行該提議。
由于Paxos算法是一套偏向理論的算法,難以理解且實(shí)現(xiàn),所以本文就不展開(kāi)介紹細(xì)節(jié)了。
2. Raft算法
Raft是一種用來(lái)管理復(fù)制狀態(tài)機(jī)的算法,復(fù)制狀態(tài)機(jī)通常使用復(fù)制日志實(shí)現(xiàn),Raft也不例外。每個(gè)服務(wù)器存儲(chǔ)一個(gè)包含一系列命令的日志,其狀態(tài)機(jī)按順序執(zhí)行日志中的命令。每個(gè)日志中的命令都相同且順序也一樣,因此只要處理相同的命令序列,就能得到相同的狀態(tài)和相同的輸出序列。這也是Raft實(shí)現(xiàn)一致性的核心思想。
Raft算法有三種角色:
- Leader(領(lǐng)袖):該角色的職責(zé)是接受和處理一切請(qǐng)求,并同步數(shù)據(jù)給Follower。
- Follower(群眾):該角色的職責(zé)是轉(zhuǎn)發(fā)請(qǐng)求給Leader,接受Leader的同步數(shù)據(jù),以及參與投票。
- Candidate(候選人):該角色的職責(zé)是競(jìng)選Leader。
這三種角色分別代表服務(wù)節(jié)點(diǎn)的三種狀態(tài),這三種狀態(tài)之間可以互相轉(zhuǎn)化。
對(duì)于raft角色的轉(zhuǎn)化,在官網(wǎng)有一個(gè)動(dòng)畫(huà),可以自己設(shè)置各節(jié)點(diǎn)的狀態(tài):https://raft.github.io/
從圖中可以看出,集群最初的狀態(tài)——所有服務(wù)器都是Follower,當(dāng)這些服務(wù)啟動(dòng)完成后,由于起初沒(méi)有Leader,所以Follower一定不會(huì)收到Leader的心跳信息。經(jīng)過(guò)一段時(shí)間后,發(fā)生選舉,此時(shí)Follower先增加自己的當(dāng)前任期號(hào)并且轉(zhuǎn)換到Candidate身份,然后投票給自己并且并行地向集群中的其他服務(wù)器節(jié)點(diǎn)發(fā)送競(jìng)選請(qǐng)求。
當(dāng)滿足以下三個(gè)條件中的一個(gè)時(shí),Candidate身份會(huì)發(fā)生轉(zhuǎn)變:
- 集群內(nèi)超過(guò)半數(shù)的服務(wù)節(jié)點(diǎn)同意該 Candidate 成為 Leader,也就是超過(guò)半數(shù)的節(jié)點(diǎn)響應(yīng)了競(jìng)選請(qǐng)求,此時(shí) Candidate 會(huì)變成 Leader。(這是對(duì)圖中“receives votes from majority of servers”的解釋)
- 集群內(nèi)其他的某個(gè)服務(wù)器節(jié)點(diǎn)已經(jīng)成為 Leader,此時(shí) Candidate 會(huì)變回 Follower。 因?yàn)楫?dāng) Leader 產(chǎn)生后,它會(huì)向其他的服務(wù)器節(jié)點(diǎn)發(fā)送心跳消息來(lái)確定自己的地位并阻止新的選舉。(這是對(duì)圖中“discovers current leader or new term”的解釋)
- 如果有多個(gè) Follower 同時(shí)成為 Candidate,那么選票可能會(huì)被瓜分,以至于沒(méi)有Candidate 贏得過(guò)半的投票,也就是選舉超時(shí)后還是沒(méi)有選出 Leader,會(huì)通過(guò)增加當(dāng)前任期號(hào)來(lái)開(kāi)始一輪新的選舉,但是這種情況有可能無(wú)限重復(fù)(這是對(duì)圖中“times out, new election”的解釋)。為了防止這種情況發(fā)生,Raft 算法使用超機(jī)選舉超時(shí)時(shí)間的方法來(lái)確保很少發(fā)生選票瓜分的情況。也就是每個(gè) Candidate 在開(kāi)始一次選舉的時(shí)候重置一個(gè)隨機(jī)的選舉超時(shí)時(shí)間,然后一直等待直到選舉超時(shí)。該 Candidate 會(huì)增加當(dāng)前的任期號(hào),重新發(fā)起競(jìng)選請(qǐng)求,此時(shí)其他 Candidate 可能還在等待中,那么其他服務(wù)節(jié)點(diǎn)認(rèn)為該超時(shí)的 Candidate 的任期號(hào)最大,所以它會(huì)被選為 Leader。
還有一種從Leader直接變成Follower的情況,這種情況多數(shù)出現(xiàn)在Leader發(fā)生了網(wǎng)絡(luò)分區(qū)的時(shí)候。當(dāng)Leader發(fā)生網(wǎng)絡(luò)分區(qū)后恢復(fù)時(shí),新的Leader已經(jīng)產(chǎn)生,它會(huì)接受新Leader的心跳請(qǐng)求,發(fā)現(xiàn)新的Leader的任期號(hào)比自己的大,它會(huì)自動(dòng)變成Follower。 而舊的Leader如果發(fā)送心跳請(qǐng)求給其他服務(wù)器節(jié)點(diǎn)時(shí),Candidate和Follower都會(huì)對(duì)比任期號(hào),如果任期號(hào)小于自己的任期號(hào),則直接拒絕此次心跳請(qǐng)求。
總結(jié)
以上是生活随笔為你收集整理的【RPC】分布式一致性与一致性协议的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ops电脑属于微型计算机吗,泽创触摸一体
- 下一篇: dsp正弦波信号发生器c语言编程实例,D