閒聊CAP、BASE與XA

CAP理論與BASE理論

首先要和大家說的就是大名鼎鼎的CAP理論與BASE理論了,這兩個理論與解決分佈式事務問題是密切相關的。

其實網上有很多關於CAP與BASE相關的文章,一寫就寫了一大堆,篇幅很長,讓人看起來頭大。王子將以最簡短的文字讓大家理解它們的含義。

CAP理論

CAP,就是Consistency、Availability、Partition Tolerence的簡稱,簡單來說,就是一致性、可用性、分區容忍性。

首先說說一致性,這不就是字面意思嗎,保證分佈式系統下各個環節的數據是一致的,準確無誤的。

再說可用性,同樣字面意思理解,保證分佈式系統出現異常、宕機情況下依然對用戶可用。

最後是分區容錯性,這個看起來不太好理解,其實你就把它理解成假如分佈式服務器之間出現網絡故障,依然可以正常運轉就行了。

所以CAP理論我們就介紹完了。

另外要說明的是CAP是不能同時滿足的,只能滿足CP或者AP。

首先既然是分佈式環境,那麼就一定涉及到網絡問題,所以P是一定要保證的。如果放棄了使用P,而選擇CA,那麼網絡出現問題時,如果各個節點都分別操作一下數據,就很可能出現數據不一致的情況,所以爲了保證C,就要禁止多節點同時寫入數據,也就是加鎖,這就違背了A的可用性要求,因爲加鎖的時候是不可用的。

BASE理論

那BASE理論又是什麼呢?

所謂的BASE,英文是Basicly Available、Soft State、Eventual Consistency,也就是基本可用、軟狀態、最終一致性。

首先說基本可用,你可以簡單理解成在分佈式系統中基本保證同時滿足CAP理論。

然後是軟狀態,我們都知道分佈式系統是無法同時保證CAP的,爲了保證數據的一致性,往往需要一段數據處理時間,這段時間內數據是可能出現不一致的,這段時間就被稱爲軟狀態。軟狀態的表現形式其實我們已經體驗過了,比如你給訂單支付的時候,會提醒你“正在支付中,請稍後”,這段時間你是不能操作訂單的。

最後是最終一致性,也就是說無論中間數據不一致的時間持續多久,最終都會保證數據的一致,這就是最終一致性,就比如消息中間件。

CAP理論與BASE理論是解決分佈式事務的基本知識,我們理解到這個程度就可以了。

 

XA規範與2PC/3PC分佈式事務

XA規範

我們先了解一下什麼是XA規範。

有個叫做X/Open的組織定義了分佈式事務的模型,這個模型中包含了幾個角色,分別是AP(Application,應用,說白了就是我們的系統),TM(Transaction Manager,分佈式事務管理器),RM(Resource Manager,資源管理器,可以理解成數據庫),CRM(Communication Resource Manager,通信資源管理器,可以是消息中間件),他們之間的關係如圖10.1所示:

分佈式事務說白了就是一個橫跨多個數據庫的事務,這個事務裏,涉及了多個數據庫的操作,然後要保證多個數據庫中,任何一個操作失敗了,其他所有庫的操作全部回滾。

而XA就是定義好的那個TM與RM之間的接口規範,XA僅僅是個規範,具體的實現是數據庫產商來提供的。

2PC

2PC說白了就是基於XA規範搞的一套分佈式事務的理論,意思就是兩階段提交,分別是準備階段和提交階段。

(1)準備階段,簡單來說就是TM先發送個prepare消息給各個數據庫,讓各個庫先把分佈式事務裏要執行的各種操作,先執行好,但不提交,同時返回一個響應消息給TM,如果成功了就發送一個成功的消息,如果失敗了就發送一個失敗的消息。

(2)提交階段,主要分爲兩種情況,一種情況就是TM接收到失敗的消息或者超時沒有接到消息,TM就認爲本次事務出現錯誤,就會發送給所有RM回滾的消息,並且認爲回滾一定會成功;另一種情況就是TM接收到成功的消息,那麼就會發送給所有RM提交的消息,並且認爲每個RM收到消息後一定會成功執行提交操作。

看到這裏,小夥伴們覺得2PC的方案可靠嗎?

沒錯,2PC的方案是不可靠的。

首先,當TM發送prepare消息給RM的時候,會鎖定資源,如果其他人要訪問這個資源就會進入阻塞狀態。

然後如果TM是一個單機的,就,會存在單點故障問題。

那麼如果我們把TM做成了雙機熱備,且支持雙機自動切換,那麼如果此時TM發送了prepare消息給某個RM,之後就發生故障,進行了備機的切換,此時這個備機是不知道之前的主機做了什麼的,就會導致狀態信息的丟失。

另外,如果有些數據庫接收到了commit消息,有些數據庫由於腦裂問題沒有接收到消息,那麼數據就出現問題了。

3PC

既然我們知道2PC的方案是不可靠的,所以當然要解決了,於是3PC方案誕生了,它就是三階段提交,過程如下:

(1)TM向RM發送CanCommit消息,然後等待RM返回結果,注意的是此時RM並沒有執行事務,其實就是檢查了一下網絡是否正連通。

(2)如果所有的RM都返回連接正常,那麼TM接着向RM發送PreCommit消息,這個階段就是2PC中的第一個階段,RM接收消息執行事務但不提交。如果有RM返回連接不正常,那麼TM就會發送abort消息給RM,直接終止事務。

(3)如果TM發送了PreCommit消息後,並接收到RM成功的響應,那麼就會發送DoCommit給RM,RM收到消息執行提交操作。如果返回了錯誤的響應或者超時未響應,那麼就發送abort消息給RM執行回滾。

簡單來講3PC就是這樣,這個時候小夥伴們就會問了,新增了一個階段到底對2PC有什麼改進呢?

這就要說到3PC的PreCommit階段了,TM發送PreCommit給RM後,各個RM是有自己的超時機制的,如果收到了PreCommit並且返回成功了,一段時間後沒有接收到TM發送的DoCommit請求,那麼RM會認爲TM出現了故障,自動執行提交操作。這樣就解決了TM單點故障的問題。

爲什麼可以這樣做呢?這就是因爲新增了一個CanCommit確認的階段。

不過雖然這樣做解決了TM的單點故障問題,但實際上還是有缺陷的。

如果TM本來是想要發送abort消息給RM的,但未發送之前就掛掉了,那麼RM超時後自動執行提交操作數據不是又出問題了。

所以2PC與3PC本質上都不能保證分佈式事務的絕對可靠。

 

總結

今天我們就先聊到這裏,有關分佈式事務的相關內容其實還有很多,下次我們再繼續閒聊。

 

往期文章推薦:

JVM專欄

消息中間件專欄

併發編程專欄

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章