對于單機下的本地事務,很顯然我們有已被實踐證明的成熟 ACID 模型來保證數(shù)據(jù)的嚴格一致性。但對于一個高訪問量、高并發(fā)的分布式系統(tǒng)來說,如果我們期望實現(xiàn)一套嚴格滿足 ACID 特性的分布式事務,很可能出現(xiàn)的情況就是在系統(tǒng)的可用性和嚴格一致性之間出現(xiàn)沖突——因為當我們要求分布式系統(tǒng)具有嚴格一致性時,很可能就要犧牲掉系統(tǒng)的可用性。但毋庸置疑的一點是,可用性又是一個所有用戶不允許我們討價還價的屬性,比如像淘寶這樣的網(wǎng)站,我們要求它 7x24 小時不間斷地對外服務。因此,我們需要在可用性和一致性之間做一些取舍,圍繞這種取舍,出現(xiàn)了兩個經(jīng)典的分布式理論——CAP 和 BASE,這兩者也是所有分布式事務協(xié)議的基石。
創(chuàng)新互聯(lián)建站專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、葫蘆島網(wǎng)站定制設(shè)計、自適應品牌網(wǎng)站建設(shè)、H5建站、商城網(wǎng)站建設(shè)、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應式網(wǎng)頁設(shè)計等建站業(yè)務,價格優(yōu)惠性價比高,為葫蘆島等各大城市提供網(wǎng)站開發(fā)制作服務。
一、CAP 定理
CAP 首次在 ACM PODC 會議上作為猜想被提出,兩年后被證明為定理,從此深深影響了分布式計算的發(fā)展。CAP 理論告訴我們,一個分布式系統(tǒng)不可能同時滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯性(Partition tolerance)這三個基本需求,最多只能同時滿足其中的兩項。
一致性:數(shù)據(jù)在多個副本之間保持一致。當有一個節(jié)點的數(shù)據(jù)發(fā)生更新后,其它節(jié)點應該也能同步地更新數(shù)據(jù)。
可用性:對于用戶的每一個操作請求,系統(tǒng)總能在有限的時間內(nèi)返回結(jié)果。
分區(qū)容錯性:分布式系統(tǒng)中的不同節(jié)點可能分布在不同的子網(wǎng)絡中,這些子網(wǎng)絡被稱為網(wǎng)絡分區(qū)。由于一些特殊原因?qū)е伦泳W(wǎng)絡之間出現(xiàn)網(wǎng)絡不連通的情況,系統(tǒng)仍需要能夠保證對外提供一致性和可用性的服務。
CAP 定理告訴了我們同時滿足這三項是不可能的,那么放棄其中的一項會是什么樣的呢?
放棄項
放棄P : 如果希望能夠避免出現(xiàn)分區(qū)容錯性問題,一種較為簡單的做法是將所有數(shù)據(jù)放在一個節(jié)點上。這樣肯定不會受網(wǎng)絡分區(qū)影響。但此時分布式系統(tǒng)也失去了意義。因此在實際的架構(gòu)設(shè)計中,P是一定要滿足的。
放棄A: 放棄可用性就是在系統(tǒng)遇到網(wǎng)絡分區(qū)或其他故障時,受影響的服務可以暫時不對外提供,等到系統(tǒng)恢復后再對外提供服務。
放棄C: 放棄一致性不代表完全放棄數(shù)據(jù)一致性,這樣的話系統(tǒng)就沒有意義了。而是放棄數(shù)據(jù)的強一致性,保留最終一致性。這樣的系統(tǒng)無法保證數(shù)據(jù)保持實時的一致性,但能夠承諾數(shù)據(jù)最終會達到一個一致的狀態(tài)。
實際的實現(xiàn)中,我們往往會把精力花在如何根據(jù)業(yè)務特點在 C(一致性)和 A(可用性)之間尋求平衡。
二、BASE 理論
BASE 是 Basically Available(基本可用)、Soft state(軟狀態(tài))和 Eventually consistent(最終一致性)三個短語的簡寫。BASE 是對 CAP 中一致性和可用性權(quán)衡的結(jié)果,其來源于對大規(guī)模互聯(lián)網(wǎng)系統(tǒng)分布式實踐的總結(jié)。其核心思想是:即使無法做到強一致性,但每個應用都可以根據(jù)自身的業(yè)務特點,采用適當?shù)姆绞絹硎瓜到y(tǒng)達到最終一致性。
基本可用:基本可用是指在分布式系統(tǒng)出現(xiàn)不可預知的故障時,允許損失部分性能。比如:正常情況下 0.5 秒就能返回結(jié)果的服務,但在故障情況(網(wǎng)絡分區(qū)或其他故障)下,需要 1~2 秒;正常情況下,電商網(wǎng)站的首頁展示的是每個用戶個性化的推薦內(nèi)容,但在節(jié)日大促的情況下,展示的是統(tǒng)一的推薦內(nèi)容。
軟狀態(tài):軟狀態(tài)是指運行系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認為該中間狀態(tài)的存在不會影響系統(tǒng)的整體可用性,即允許系統(tǒng)在不同節(jié)點的數(shù)據(jù)副本之間進行數(shù)據(jù)同步的過程存在延時。比如秒殺系統(tǒng)中,用戶余額的扣減和商家余額的增加可以存在延時,當用戶余額減了之后即可返回支付成功,商家余額的增加可以等系統(tǒng)壓力小的時候再做。
最終一致性:最終一致性強調(diào)的是系統(tǒng)中所有的數(shù)據(jù)副本,在經(jīng)過一段時間的同步后,最終能達到一個一致的狀態(tài)。這也是分布式系統(tǒng)的一個基本要求。
嚴格遵守 ACID 的分布式事務我們稱為剛性事務,而遵循 BASE 理論的事務我們稱為柔性事務。在分布式環(huán)境下,剛性事務會讓系統(tǒng)的可用性變得難以忍受,因此實際生產(chǎn)中使用的分布式事務都是柔性事務,其中使用最多的就是 2PC、3PC 和 TCC。
三、2PC 協(xié)議
2PC 是二階段提交(Two-phase Commit)的縮寫,顧名思義,這個協(xié)議分兩階段完成。第一個階段是準備階段,第二個階段是提交階段,準備階段和提交階段都是由事務管理器(協(xié)調(diào)者)發(fā)起的,協(xié)調(diào)的對象是資源管理器(參與者)。二階段提交協(xié)議的概念來自 X/Open 組織提出的分布式事務的規(guī)范 XA 協(xié)議,協(xié)議主要定義了(全局)事務管理器和(局部)資源管理器之間的接口。XA 接口是雙向的系統(tǒng)接口,在事務管理器以及一個或多個資源管理器之間形成通信橋梁。Java 平臺上的事務規(guī)范 JTA(Java Transaction API)提供了對 XA 事務的支持,它要求所有需要被分布式事務管理的資源(由不同廠商實現(xiàn))都必須實現(xiàn)規(guī)定接口(XAResource 中的 prepare、commit 和 rollback 等)。
兩階段如下:
準備階段:協(xié)調(diào)者向參與者發(fā)起指令,參與者評估自己的狀態(tài),如果參與者評估指令可以完成,參與者會寫 redo 和 undo 日志,然后鎖定資源,執(zhí)行操作,但是并不提交。
提交階段:如果每個參與者明確返回準備成功,也就是預留資源和執(zhí)行操作成功,協(xié)調(diào)者向參與者發(fā)起提交指令,參與者提交資源變更的事務,釋放鎖定的資源;如果任何一個參與者明確返回準備失敗,也就是預留資源或者執(zhí)行操作失敗,協(xié)調(diào)者向參與者發(fā)起中止指令,參與者取消已經(jīng)變更的事務,執(zhí)行 undo 日志,釋放鎖定的資源。
兩階段提交協(xié)議成功場景示意圖如下:
我們看到兩階段提交協(xié)議在準備階段鎖定資源,是一個重量級的操作,并能保證強一致性,但是實現(xiàn)起來復雜、成本較高,不夠靈活,更重要的是它有如下致命的問題:
阻塞:從上面的描述來看,對于任何一次指令必須收到明確的響應,才會繼續(xù)做下一步,否則處于阻塞狀態(tài),占用的資源被一直鎖定,不會被釋放。
單點故障:如果協(xié)調(diào)者宕機,參與者沒有了協(xié)調(diào)者指揮,會一直阻塞,盡管可以通過選舉新的協(xié)調(diào)者替代原有協(xié)調(diào)者,但是如果之前協(xié)調(diào)者在發(fā)送一個提交指令后宕機,而提交指令僅僅被一個參與者接受,并且參與者接收后也宕機,新上任的協(xié)調(diào)者無法處理這種情況。
腦裂:協(xié)調(diào)者發(fā)送提交指令,有的參與者接收到執(zhí)行了事務,有的參與者沒有接收到事務,就沒有執(zhí)行事務,多個參與者之間是不一致的。
上面所有的這些問題,都是需要人工干預處理,沒有自動化的解決方案,因此兩階段提交協(xié)議在正常情況下能保證系統(tǒng)的強一致性,但是在出現(xiàn)異常情況下,當前處理的操作處于錯誤狀態(tài),需要管理員人工干預解決,因此可用性不夠好,這也符合 CAP 定理的一致性和可用性不能兼得的原理。
四、3PC 協(xié)議
三階段提交協(xié)議(3PC 協(xié)議)是兩階段提交協(xié)議的改進版本。它通過超時機制解決了阻塞的問題,并且把兩個階段增加為三個階段:
詢問階段:協(xié)調(diào)者詢問參與者是否可以完成指令,協(xié)調(diào)者只需要回答是還是不是,而不需要做真正的操作,這個階段參與者在等待超時后會自動中止。
準備階段:如果在詢問階段所有的參與者都返回可以執(zhí)行操作,協(xié)調(diào)者向參與者發(fā)送預執(zhí)行請求,然后參與者寫 redo 和 undo 日志,鎖定資源,執(zhí)行操作,但是不提交操作;如果在詢問階段任何參與者返回不能執(zhí)行操作的結(jié)果,則協(xié)調(diào)者向參與者發(fā)送中止請求,這里的邏輯與兩階段提交協(xié)議的的準備階段是相似的,這個階段參與者在等待超時后會自動提交。
提交階段:如果每個參與者在準備階段返回準備成功,也就是預留資源和執(zhí)行操作成功,協(xié)調(diào)者向參與者發(fā)起提交指令,參與者提交資源變更的事務,釋放鎖定的資源;如果任何一個參與者返回準備失敗,也就是預留資源或者執(zhí)行操作失敗,協(xié)調(diào)者向參與者發(fā)起中止指令,參與者取消已經(jīng)變更的事務,執(zhí)行 undo 日志,釋放鎖定的資源,這里的邏輯與兩階段提交協(xié)議的提交階段一致。
三階段提交協(xié)議成功場景示意圖如下:
這里與兩階段提交協(xié)議有兩個主要的不同:
增加了一個詢問階段,詢問階段可以確保盡可能早的發(fā)現(xiàn)無法執(zhí)行操作而需要中止的行為,但是它并不能發(fā)現(xiàn)所有的這種行為,只會減少這種情況的發(fā)生。
增加了等待超時的處理邏輯,如果在詢問階段等待超時,則自動中止;如果在準備階段之后等待超時,則自動提交。這也是根據(jù)概率統(tǒng)計上的正確性最大。
三階段提交協(xié)議相比二階段提交協(xié)議,避免了資源被無限鎖定的情況。但也增加了系統(tǒng)的復雜度,增加了參與者和協(xié)調(diào)者之間的通信次數(shù)。
五、TCC 協(xié)議
無論是 2PC 還是 3PC,都存在一個大粒度資源鎖定的問題。為了解釋這個問題,我們先來想象這樣一種場景,用戶在電商網(wǎng)站購買商品1000元,使用余額支付800元,使用紅包支付200元。我們看一下在 2PC 中的流程:
prepare 階段:
下單系統(tǒng)插入一條訂單記錄,不提交
余額系統(tǒng)減 800 元,給記錄加鎖,寫 redo 和 undo 日志,不提交
紅包系統(tǒng)減 200 元,給記錄加鎖,寫 redo 和 undo 日志,不提交
commit 階段:
下單系統(tǒng)提交訂單記錄
余額系統(tǒng)提交,釋放鎖
紅包系統(tǒng)提交,釋放鎖
為什么說這是一種大粒度的資源鎖定呢?是因為在 prepare 階段,當數(shù)據(jù)庫給用戶余額減 800 元之后,為了維持隔離性,會給該條記錄加鎖,在事務提交前,其它事務無法再訪問該條記錄。但實際上,我們只需要預留其中的 800 元,不需要鎖定整個用戶余額。這是 2PC 和 3PC 的局限,因為這兩者是資源層的協(xié)議,無法提供更靈活的資源鎖定操作。為了解決這個問題,TCC 應運而生。TCC 本質(zhì)上也是一個二階段提交協(xié)議,但和 JTA 中的二階段協(xié)議不同的是,它是一個服務層的協(xié)議,因此開發(fā)者可以根據(jù)業(yè)務自由控制資源鎖定的粒度。我們等會兒可以看到 TCC 在上面這個場景中的優(yōu)勢,但在那之前,我們先來看一下 TCC 協(xié)議的運行過程。
TCC 將事務的提交過程分為 try-confirm-cancel(實際上 TCC 就是 try、confirm、cancel 的簡稱) 三個階段:
try:完成業(yè)務檢查、預留業(yè)務資源
confirm:使用預留的資源執(zhí)行業(yè)務操作(需要保證冪等性)
cancel:取消執(zhí)行業(yè)務操作,釋放預留的資源(需要保證冪等性)
和 JTA 二階段事務的參與方都要實現(xiàn) prepare、commit、rollback 一樣,TCC 的事務參與方也必須實現(xiàn) try、confirm、cancel 三個接口。流程如下:
事務發(fā)起方向事務協(xié)調(diào)器發(fā)起事務請求,事務協(xié)調(diào)器調(diào)用所有事務參與者的 try 方法完成資源的預留,這時候并沒有真正執(zhí)行業(yè)務,而是為后面具體要執(zhí)行的業(yè)務預留資源,這里完成了一階段。
如果事務協(xié)調(diào)器發(fā)現(xiàn)有參與者的 try 方法預留資源時候發(fā)現(xiàn)資源不夠,則調(diào)用參與方的 cancel 方法回滾預留的資源,需要注意 cancel 方法需要實現(xiàn)業(yè)務冪等,因為有可能調(diào)用失敗(比如網(wǎng)絡原因參與者接受到了請求,但是由于網(wǎng)絡原因事務協(xié)調(diào)器沒有接受到回執(zhí))會重試。
如果事務協(xié)調(diào)器發(fā)現(xiàn)所有參與者的 try 方法返回都 OK,則事務協(xié)調(diào)器調(diào)用所有參與者的 confirm 方法,不做資源檢查,直接進行具體的業(yè)務操作。
如果協(xié)調(diào)器發(fā)現(xiàn)所有參與者的 confirm 方法都 OK 了,則分布式事務結(jié)束。
如果協(xié)調(diào)器發(fā)現(xiàn)有些參與者的 confirm 方法失敗了,或者由于網(wǎng)絡原因沒有收到回執(zhí),則協(xié)調(diào)器會進行重試。這里如果重試一定次數(shù)后還是失敗,會怎么樣?常見的是做事務補償。
TCC 執(zhí)行場景示意圖如下:
現(xiàn)在我們再回到開始的那個支付場景中,看看 TCC 在該場景中的流程:
Try操作
tryX 下單系統(tǒng)創(chuàng)建待支付訂單
tryY 凍結(jié)賬戶紅包 200 元
tryZ 凍結(jié)資金賬戶 800 元
Confirm操作
confirmX 訂單更新為支付成功
confirmY 扣減賬戶紅包 200 元
confirmZ 扣減資金賬戶 800 元
Cancel操作
cancelX 訂單處理異常,資金紅包退回,訂單支付失敗
cancelY 凍結(jié)紅包失敗,賬戶余額退回,訂單支付失敗
cancelZ 凍結(jié)余額失敗,賬戶紅包退回,訂單支付失敗
可以看到,我們使用了凍結(jié)代替了原先的賬號鎖定(實際操作中,凍結(jié)操作可以用數(shù)據(jù)庫減操作+日志實現(xiàn)),這樣在凍結(jié)操作之后,事務提交之前,其它事務也能使用賬戶余額,提高了并發(fā)性。
總結(jié)一下,相比于二階段提交協(xié)議,TCC 主要有以下區(qū)別:
2PC 位于資源層而 TCC 位于服務層。
2PC 的接口由第三方廠商實現(xiàn),TCC 的接口由開發(fā)人員實現(xiàn)。
TCC 可以更靈活地控制資源鎖定的粒度。
TCC 對應用的侵入性強。業(yè)務邏輯的每個分支都需要實現(xiàn) try、confirm、cancel 三個操作,應用侵入性較強,改造成本高。
文章題目:分布式事務——2PC、3PC和TCC
URL地址:http://chinadenli.net/article8/gsppip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、品牌網(wǎng)站制作、網(wǎng)站收錄、網(wǎng)站改版、定制開發(fā)、網(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)