圖文精講java常見分布式事務(wù)理論與解決方案_第1頁
圖文精講java常見分布式事務(wù)理論與解決方案_第2頁
圖文精講java常見分布式事務(wù)理論與解決方案_第3頁
圖文精講java常見分布式事務(wù)理論與解決方案_第4頁
圖文精講java常見分布式事務(wù)理論與解決方案_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第圖文精講java常見分布式事務(wù)理論與解決方案目錄CAP理論C(Consistence):一致性A(Availability):可用性P(Partitiontolerance):分區(qū)容錯性BASE理論BA(BasicallyAvailable):基本可用S(Soft-state):軟狀態(tài)E(EventuallyConsistent):最終一致性一致性hashGossip協(xié)議Gossip協(xié)議的特點:Raft算法選舉復(fù)制分布式事務(wù)2PC3PCTCC如何解決某個節(jié)點故障的問題?如何解決數(shù)據(jù)一致性的問題?如何解決數(shù)據(jù)傾斜的問題?

CAP理論

先從定義開始:

C(Consistence):一致性

所有的節(jié)點訪問的是最新的數(shù)據(jù)副本,這是什么意思呢?我們知道在分布式系統(tǒng)中,為了高可用,往往一個節(jié)點會有若干個數(shù)據(jù)副本,簡稱Follower節(jié)點,比較常見的模式是我們的數(shù)據(jù)更新一般會寫入Leader節(jié)點,然后會同步給Follower節(jié)點,當我們讀取數(shù)據(jù)的時候,不論從哪個節(jié)點讀取都可以讀到最新的數(shù)據(jù),這就是一致性。

A、B、C可以得到同樣的數(shù)據(jù)。

A(Availability):可用性

非故障節(jié)點可以正常的操作,簡單來說就是客戶端一直可以正常訪問并得到系統(tǒng)的正常響應(yīng),從用戶角度來看就是不會出現(xiàn)系統(tǒng)操作失敗或者訪問超時等問題,但是系統(tǒng)內(nèi)部可能會出現(xiàn)網(wǎng)絡(luò)延遲等問題。

C節(jié)點因為自身問題不可用,正常情況會被剔除,B節(jié)點與A節(jié)點之間可能存在同步延遲,但是B節(jié)點本身沒有故障,所以B節(jié)點是可用的。

P(Partitiontolerance):分區(qū)容錯性

網(wǎng)絡(luò)的問題錯綜復(fù)雜,分布式系統(tǒng)肯定是要考慮這一點的,如果出現(xiàn)某個節(jié)點因為網(wǎng)絡(luò)等問題造成數(shù)據(jù)不一致,或者數(shù)據(jù)延遲很久才同步過來,雖然會影響部分節(jié)點數(shù)據(jù)的時效性,但是服務(wù)節(jié)點依然是可用的,分布式系統(tǒng)要能容忍這種情況的。

B對應(yīng)的節(jié)點雖然和Leader斷了聯(lián)系,但是依然可以對外服務(wù),只不過提供的是老數(shù)據(jù)。

在分布式系統(tǒng)中,CAP是無法同時滿足的,首先由于存在多節(jié)點,并且網(wǎng)絡(luò)傳輸需要時間,所以可能會存在延遲,那么節(jié)點之間的數(shù)據(jù)我們無法保證某一時刻完全一致,因此P(分區(qū)容錯性)是要滿足的。在P滿足的情況下,為什么說CA不能同時滿足呢?我們來通過假設(shè)看一看,如果CA同時滿足會怎么樣。

假設(shè)現(xiàn)在要求滿足C(一致性),那么就是說所有的節(jié)點在某一刻提供的數(shù)據(jù)都必須一致,我們知道在P的情況,是不可能保證的,要保證的話,就只能把其他節(jié)點全部干掉,比如禁止讀寫,那這其實就是和A是相悖的(某些節(jié)點雖然延遲,但是節(jié)點本身可用)。

假設(shè)現(xiàn)在要求滿足A(可用性),那么就是說只要節(jié)點本身沒什么問題,就可以對外提供服務(wù),哪怕有點數(shù)據(jù)延遲,很明顯這肯定是和C相悖的。

在實際的業(yè)務(wù)中,我們需要根據(jù)業(yè)務(wù)的場景來決定使用CP,還是AP。比如對一些和錢掛鉤的業(yè)務(wù),數(shù)據(jù)的一致性按道理應(yīng)該是最重要的,因此一般會采用CP,而對于一些不影響主體功能的業(yè)務(wù),比如像新聞的閱讀量,不同的用戶看到的閱讀量不一樣并不會造成什么影響,可以采用AP。

BASE理論

由于CAP理論中C和A無法兼得,eBay的架構(gòu)師提出了BASE理論,BASE理論主要是在CA之間做文章,它不要求強一致性,因此可以滿足一定的可用性。我們還是先從定義開始:

BA(BasicallyAvailable):基本可用

注意這個和不可用不是一回事,在分布式系統(tǒng)中出現(xiàn)不可預(yù)估的故障時,允許損失部分可用性,保證核心功能可用,比如正常一個接口響應(yīng)200ms,在出現(xiàn)故障時響應(yīng)超過1s,雖然響應(yīng)時間變長了,但是接口還是可以對外提供服務(wù)的,再比如對于一個視頻網(wǎng)站,在突發(fā)流量到來時,把視頻的彈幕服務(wù)打掛了,但是視頻的播放功能依然正常。

S(Soft-state):軟狀態(tài)

即分布式系統(tǒng)允許存在一個中間的狀態(tài),但是這個中間狀態(tài)并不會對服務(wù)造成嚴重的影響,比如對于主從復(fù)制這種,允許從節(jié)點短暫的延遲。

E(EventuallyConsistent):最終一致性

由于軟狀態(tài)的存在,系統(tǒng)對延遲是可以容忍的,但是在一段時間后,延遲的數(shù)據(jù)需要最終保持一致。

總的來說,BASE理論適用性應(yīng)該更廣泛,很多時候我們并不要求數(shù)據(jù)的強一致性,只要在短暫的延時之后能達到一致性也是可以的。

一致性hash

hash這個詞對我們來說并不陌生,以緩存服務(wù)器來說,一般會在線上配置好幾臺服務(wù)器,然后根據(jù)hash來決定請求哪臺緩存服務(wù),比如常見的就是取模方式

hash(key)%num

來獲取目標機器。

假設(shè)現(xiàn)在有3臺緩存服務(wù)器,并且當前有3個緩存的key,分別是k0,k1,k2,在經(jīng)過hash以后,它們的分布情況如下:

hash(k0)%3=0#No.0

hash(k1)%3=1#No.1

hash(k2)%3=2#No.2

很幸運,分布的非常均勻,每臺機器一個。某天,由于線上要做個活動,預(yù)計訪問量會加大,需要選擇加一臺服務(wù)器來分擔壓力,于是經(jīng)過hash之后,k0,k1,k2的分布情況如下:

hash(k0)%4=0#No.1

hash(k1)%4=1#No.2

hash(k2)%4=2#No.3

k0的目標緩存服務(wù)器由原本的No.0變成了No.1

k1的目標緩存服務(wù)器由原本的No.1變成了No.2

k2的目標緩存服務(wù)器由原本的No.2變成了No.3

可以發(fā)現(xiàn)因為添加了一臺緩存節(jié)點,導(dǎo)致了k0,k1,k2原來的緩存全部失效了,這似乎有點問題,類似緩存雪崩,嚴重的話會對DB造成很大的壓力,造成這個問題的主要原因是因為我們加了一個節(jié)點,導(dǎo)致hash結(jié)果發(fā)生了變動,此時的hash可以說是不穩(wěn)定的。

為了解決rehash不穩(wěn)定的問題,于是出現(xiàn)了一致性hash算法。一致性hash的原理比較簡單,首先存在一個hash圓環(huán),這個圓環(huán)可以存放0-2^32-1個節(jié)點。

第一步就是把我們的目標服務(wù)器節(jié)點通過hash映射到這個環(huán)上

第二步根據(jù)我們需要查找的key,它應(yīng)該也對應(yīng)hash環(huán)上的某個位置

也許你會問,這k0、k1、k2也沒和某個緩存節(jié)點對上呀~,這就是一致性hash不同的地方,它此時查找的方式并不是

hash(key)=某個節(jié)點,而是根據(jù)key的位置,順時針找到第一個節(jié)點,這個節(jié)點就是當下這個key的目標節(jié)點。

我們再來看看在一致性hash的情況下,新增一個節(jié)點會發(fā)生什么。

此時唯一的變動就是k0原本應(yīng)該打到cache0節(jié)點的,現(xiàn)在卻打到了我們新加的節(jié)點cache3上,而k1,k2是不變的,也就是說有且只有k0的緩存失效了,相比之前,大大降低了緩存失效的面積。

當然這樣的節(jié)點分布算是比較理想的了,如果我們的節(jié)點是這樣分布的:

幾個cache節(jié)點分布的比較集中,由于順時針查找法,所以最終k0,k1,k2都落在cache0節(jié)點上,也就是說cache1、cache2基本就是多余的,所以為了解決這種數(shù)據(jù)傾斜的問題,一致性hash又引入了虛擬節(jié)點的概念,每個節(jié)點可以有若干個虛擬節(jié)點,比如:

cache0-cache0#1

cache1-cache1#1

cache2-cache2#1

虛擬節(jié)點并不是真正的服務(wù)節(jié)點,它只是一個影子,它的目的就是站坑位,讓節(jié)點更加分散,更加均勻。

這樣通過映射出虛擬節(jié)點以后,k0打到cache2,k1打到cache0,k2打到cache1,虛擬節(jié)點越多,理論分布的越均勻。

Gossip協(xié)議

集群往往是由多個節(jié)點共同組成的,當一個節(jié)點加入集群或者一個節(jié)點從集群中下線的時候,都需要讓集群中其他的節(jié)點知道,這樣才能將數(shù)據(jù)信息分享給新節(jié)點而忽略下線節(jié)點。

A、B、C節(jié)點之間可以互相傳遞消息,但是D節(jié)點在下線之后會被廣播告訴其他存活節(jié)點。

這樣的廣播協(xié)議就是今天要說Gossip協(xié)議,Gossip協(xié)議也叫Epidemic協(xié)議(流行病協(xié)議),當一個消息到來時,通過Gossip協(xié)議就可以像病毒一樣感染全部集群節(jié)點,當然我們利用的是它這個極強的散播能力。

Gossip的過程是由一個種子節(jié)點發(fā)起的,當一個種子節(jié)點有信息需要同步到網(wǎng)絡(luò)中的其他節(jié)點時,它會隨機的選擇周圍幾個節(jié)點散播消息,收到消息的節(jié)點也會重復(fù)該過程,直至最終網(wǎng)絡(luò)中所有的節(jié)點都收到了消息。這個過程可能需要一定的時間,所以不能保證某個時間點所有的節(jié)點都有該條消息,但是理論上最終所有節(jié)點都會收到消息,因此它是一個最終一致性協(xié)議。

Gossip協(xié)議的特點:

Gossip協(xié)議是周期性散播消息,每隔一段時間傳播一次

被感染的節(jié)點,每次可以繼續(xù)散播N個節(jié)點

每次散播消息時,都會選擇尚未發(fā)送過的節(jié)點進行散播

收到消息的節(jié)點,不會向發(fā)送的節(jié)點散播

同一個節(jié)點可能會收到重復(fù)的消息,因為可能同時多個節(jié)點正好向它散播

集群是去中心化的,節(jié)點之間都是平等的

消息的散播不用等接收節(jié)點的ack,即消息可能會丟失,但是最終應(yīng)該會被感染

我們來看個例子:

種子節(jié)點是A

A節(jié)點選擇B、C節(jié)點進行散播

C散播到D,B散播D和E,可以發(fā)現(xiàn)D收到兩次

D散播到F,最終整個網(wǎng)絡(luò)都同步到了消息

Gossip有點類似圖的廣度優(yōu)先遍歷算法,一般用于網(wǎng)絡(luò)拓撲結(jié)構(gòu)信息的分享和維護,像redis、consul都有使用到。

Raft算法

分布式協(xié)議的難點之一就是數(shù)據(jù)的一致性,當由多個節(jié)點組成的集群中只有一個節(jié)點收到數(shù)據(jù),我們就算成功的話,風(fēng)險太大,當要求所有節(jié)點都收到數(shù)據(jù)才響應(yīng)成功,性能又太差,所以一般會在數(shù)據(jù)的安全和性能之間做個折中,只要保證絕大部分節(jié)點同步數(shù)據(jù)成功,我們就算成功,Raft算法作為比較知名的一致性算法,被廣泛應(yīng)用于許多中間件中,比如像etcd,接下來我們就看看Raft算法是如何工作的。

首先介紹下在Raft算法中,幾種情況下每個節(jié)點對應(yīng)的角色:

Leader節(jié)點:同大多數(shù)分布式中的Leader節(jié)點一樣,數(shù)據(jù)的變更都是通過它的

Follower節(jié)點:Leader節(jié)點的追隨者,負責(zé)復(fù)制數(shù)據(jù)并且在選舉時候投票的節(jié)點

Candidate候選節(jié)點:參與選舉的節(jié)點,就是Follower節(jié)點參與選舉時會切換的角色

Raft算法將一致性問題分解為兩個的子問題,Leader選舉和狀態(tài)復(fù)制。

選舉

首先我們來看看Leader的選舉,系統(tǒng)在剛開始的時候,所有節(jié)點都為Follower節(jié)點,這時大家都有機會參與選舉,也就是把自己變成Candidate,但是如果每個Follower節(jié)點都變成Candidate那么就會陷入無限的死循環(huán),于是每個Follower都一個定時器,并且定時器的時間是隨機的,當某個Follower的定時器時間走完之后,會確認當前是否存在Leader節(jié)點,如果不存在就會把自己變成Candidate,這時會投自己1票,同時告訴其它節(jié)點,讓它們來投票,當拿到超過半數(shù)以上的投票時,當前的Candidate就會變成Leader節(jié)點。

由于A節(jié)點的定時器時間最短(10ms),所以A會成為Candidate

A投自己一票,同時B、C也投出自己的同意票,因此A會變成Leader節(jié)點,同時會記錄是第M任。這個M是做版本校驗的,比如一個編號是10的節(jié)點,收到了一個編號是9的節(jié)點的投票請求,那么就會拒絕這個請求。

在Leader節(jié)點選舉出來以后,Leader節(jié)點會不斷的發(fā)送心跳給其它Follower節(jié)點證明自己是活著的,其他Follower節(jié)點在收到心跳后會清空自己的定時器,并回復(fù)給Leader,因為此時沒必要觸發(fā)選舉了。

如果Leader節(jié)點在某一刻掛了,那么Follower節(jié)點就不會收到心跳,因此在定時器到來時就會觸發(fā)新一輪的選舉,流程還是一樣,但是如果恰巧兩個Follower都變成了Candidate,并且都得到了同樣的票數(shù),那么此時就會陷入僵局,為了打破僵局,這時每個Candidate都會隨機推遲一段時間再次請求投票,當然一般情況下,就是先來先得,優(yōu)先跑完定時器的Candidate理論成為Leader的概率更大。

好的選舉流程大致如上,接下來我們來看看數(shù)據(jù)的復(fù)制。

復(fù)制

當Leader節(jié)點收到Client的請求變更時,會把變更記錄到log中,然后Leader會將這個變更隨著下一次的心跳通知給Follower節(jié)點,收到消息的Follower節(jié)點把變更同樣寫入日志中,然后回復(fù)Leader節(jié)點,當Leader收到大多數(shù)的回復(fù)后,就把變更寫入自己的存儲空間,同時回復(fù)client,并告訴Follower應(yīng)用此log。至此,集群就變更達成了共識。

最后,Raft算法是能夠?qū)崿F(xiàn)分布式系統(tǒng)強一致性的算法,每個系統(tǒng)節(jié)點有三種狀態(tài)Leader、Follower、Candidate,實現(xiàn)Raft算法兩個最重要的事是:主的選舉和日志的復(fù)制。

分布式事務(wù)

事務(wù)相信大家不陌,事務(wù)的本質(zhì)是要么一起向前沖,要么一起保持不動。對于MySQL的InnoDB來說,我們只需要執(zhí)行begin、commit就行,有時候我們可能需要回滾rollback。但是這是在同一數(shù)據(jù)庫的前提下,如果我們的數(shù)據(jù)表分庫了或者說我們要操作的資源在不同的網(wǎng)絡(luò)節(jié)點上該怎么辦?這就得用到我們今天要說的分布式事務(wù)了,分布式事務(wù)有2PC、3PC、TCC等,但是無論哪種都無法保證完美的ACID,我們來一起看看是怎么回事吧。

2PC

從名字可以看出它是分兩個階段的,所以它也叫做二階段提交,即準備和提交,2PC要求有個事務(wù)的協(xié)調(diào)者,相比常規(guī)的事務(wù),我們的請求是發(fā)給這個協(xié)調(diào)者的,然后由協(xié)調(diào)者幫我們協(xié)調(diào)各個節(jié)點資源的提交。

準備階段:協(xié)調(diào)者會讓各個參與事務(wù)的參與者,把除了提交之外所有的事情都干好,也就是就等著提交了

提交階段:協(xié)調(diào)者收到各個參與者的準備消息后,根據(jù)準備情況通知各個參與者提交(commit)或者回滾(rollback)

可以發(fā)現(xiàn)整個過程非常依賴協(xié)調(diào)者,如果協(xié)調(diào)者掛了,那么整個分布式事務(wù)就不可用,所以一般建議協(xié)調(diào)者至少有個備份節(jié)點。

如果協(xié)調(diào)者在收到所有節(jié)點的ok之后,在準備發(fā)送commit消息的時候,由于網(wǎng)絡(luò)問題,導(dǎo)致其中一個節(jié)點始終收不到消息,那么收不到消息的節(jié)點就會一直占著資源不釋放,出現(xiàn)這種情況的時候,建議協(xié)調(diào)者有個重試功能,在commit失敗之后,不停的重試,直至成功。2PC協(xié)議是一種強一致性協(xié)議,它是同步阻塞的,所以在高并發(fā)的場景它的性能可能還會有問題。

3PC

2PC存在一些問題,比如協(xié)調(diào)者從掛了到恢復(fù)后并不知道當前節(jié)點的狀態(tài),現(xiàn)在應(yīng)該做什么(是該提交還是回滾等等),還有就是當發(fā)生網(wǎng)絡(luò)問題的時候,無法通信的節(jié)點只會傻傻的等待,造成資源一直處于鎖定狀態(tài)。鑒于這些問題,出現(xiàn)了3PC。

首先3PC顧名思義,會分為3個階段,分別是準備階段、預(yù)提交階段和提交階段。

準備階段:主要是詢問參與者自身的狀況,比如你的負載情況如何?能參與接下來的任務(wù)吧?

預(yù)提交階段:除了commit之外的所有準備工作,就等著commit了

提交階段:執(zhí)行真正的commit或者rollback

如果在事務(wù)期間,有新的協(xié)調(diào)者頂替進來,它就可以根據(jù)一個參與者的狀態(tài)來判斷當前應(yīng)該干嘛,比如如果一個參與者處于提交階段,那么表明當前的事務(wù)正處于提交階段。當因為網(wǎng)絡(luò)問題某個節(jié)點一直收不到提交信息,那么此時也不會傻等了,會有超時時間,當超時時

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論