閑聊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本質上都不能保證分散式事務的絕對可靠。
總結
今天我們就先聊到這裡,有關分散式事務的相關內容其實還有很多,下次我們再次繼續閑聊。
往期文章推薦: