啥?分布式啥?啥事务?
二將軍問題
我們先來看個故事,相信會有助于你對分布式事務的理解。二將軍問題是一個計算機領域一個經典的問題。
「故事背景」黑白兩軍交戰之際,兩股白軍將黑軍被圍困在山谷之中;山谷兩側任意一股白軍都比山谷中的黑軍人數少,因此單獨一只白軍向黑軍發起進攻,必敗無疑,但是兩股白軍人數總和卻比黑軍人數多,若能同時向黑軍發起進攻,則可大勝。而山谷左右側的白軍相互通信(告知進攻時間)必然會穿過山谷,但是有被黑軍俘虜的風險,如果你是山谷左側的白軍統帥,你會如何抉擇呢?
「戰況分析」
「情形1」:送信失敗,如下圖所示,左側白軍穿過山谷的時候被黑軍俘虜了,右側白軍仍舊不知道左側白軍的進攻信息。
「情形2」:送信成功,回信失敗。如下圖所示,左側白軍穿過山谷將信息成功通知給右側白軍,但是右側白軍攜帶"收到命令"的信息,穿過山谷向左側白軍通知的時候被黑軍俘虜了,此時左側白軍不知道右側白軍是否接收到進攻命令。
「情形3」:送信成功,回信成功,如下圖所示,白軍勝利毫無疑問。
「戰役復盤」
面對不穩定的信息傳輸通道(山谷中的黑軍),要完成兩股白軍的通信是有難度的,送信回信的過程就好比我們系統中Send和Ack 的過程,并且只要送信或者回信任意一次失敗,整個信息傳遞就標志著失敗,無法完成進攻,這像不像CAP的最佳打開方式 中提到的原子性,事務中的每個操作都成功,事務才會提交。
如果真的發生了情形1和情形2,如果你是左側白軍的統帥或者右側白軍的負責人,你該怎么辦呢?是不是應該等等,看看有沒有回信,如果長時間沒有回信就認為這個送信的人被俘虜了,再派1個人重復送信的過程,這就是我們在系統中常見的超時重試。當然重試一定是有限制的,如果真的無限重試。那么左右側白軍人數有可能會清零(資源耗盡),戰爭自然失敗(系統自然崩潰)
如果左側白軍派遣多名士兵同時發起送信的動作,那么對于右側白軍來說不管收到多少次信息,都只進攻一次。類比咱們系統來說,對于不管是一次請求還是多次請求,結果都是一樣的,這就是系統冪等性
這個二軍問題,像不像TCP鏈接的握手的過程呢?問題來了,為什么是三次握手,而不是兩次握手?文章留言回復下,如果你不知道可要補課啦
?
本地事務
本地事務實際上是指傳統的事務,也就是大學課程里數據庫原理中的提到事務。在CAP的最佳打開方式的文章中,我們也可以看到,ACID就是本地事務的最好詮釋,原子性、一致性、隔離性、持久性,詳細解釋不再贅述,可以參看CAP篇中的含義。
當時我是用的午休去超市買蘋果來舉例,我們再簡單重溫下本地事務。當我在超市選好蘋果去結賬的時候,超市系統突然崩了無法結賬,雖然選好了蘋果,但也沒啥用,雖然這次買蘋果的事務自然而然也就失敗了。但是對于超市來說,所有數據都不曾有任何變化,這就是本地事務。
?
分布式事務
我們沿著本地事務的思路繼續深入,這次超市系統崩了的原因是超市發展很快,數據量的不斷增長,導致后端單數據庫性能已經達到了瓶頸,于是開始進行分庫(分到多個物理實例)原來在單庫中會操作多個表,由于不涉及網絡傳輸,直接通過RDBMS的undo log、redo log以及鎖機制就可以滿足本地事務的所有需求了,但是分庫后,意味著出現了跨庫、跨網絡的的事務場景。
舉個例子,在分庫前,優惠券邏輯使用的表A和支付邏輯相關的表B在同一個庫中的,此時超市有蘋果促銷的活動,使用優惠券和支付邏輯是在同一個事務中,因此在操作支付時,如果支付失敗,本地事務會強制將使用優惠券的操作也會失敗。而由于分庫拆分成兩個獨立實例,也就導致在跨網絡的情況下,無法將單機事務在數據資源層面完美支持,因此介于此種情況,自然而然有了分布式事務的應用場景。
我們來明確下什么是分布式事務,通常分布式事務中存在兩種角色
資源管理器(Resource Manager, RM)即事務參與者
事務管理器(Transaction Manager, TM)即事務協調者
在分布式事務的模型中,RM對應著資源,一個DB、一個被依賴服務都是一個RM;而TM 是一個全局事務管理器,一個TM會管理多個RM,就類似上面我們的超市促銷支付的邏輯去協調多方數據庫資源,從而協調各個本地事務的進度,使其共同提交或回滾,最終達成一種全局的 ACID 特性。
?
兩種事務的區別
實際上與分布式系統CAP類似,分布式事務中涉及到的所有參與者會分布在同一個網絡環境中,參與者會通過相互通信達到分布式系統的一致性,但因為網絡環境的不確定性,網絡不可避免的會出現超時、失敗的情況,進而可能導致數據出現不一致的情況。而本地事務并不需要多次rpc,自然也就也就不存在分布式一致性問題,分布式一致性的核心點在于數據的分布式操作,導致本地事務無法保證數據的原子性。
舉個實際的????,我們工作中經常會有獨立負責一個項目的情況,自己會了解項目的所有邏輯,不需要和其他人交互。此時如果項目參與的人數增加到多個,成立了一個項目組,要想順利的繼續完成項目,就會導致你經常需要和項目組的其他人進行交流,保持目標/進度的一致,此時這個項目組就是分布式系統,每一個項目組成員就是分布式系統中的節點。由于溝通的不確定性,當某個模塊廢棄時,除了自己本地修改外,還需要通知所有人修改。這時如果溝通的不到位,就會出現不一致的情況。因此在分布式事務中會出現一個全局協調者的角色(TM),協調所有資源(RM)步調,保證全局一致。
?
分布式事務的場景
「資源主導」
上面超市買蘋果的例子僅僅是舉了一個由于分庫而引發的分布式事務場景,我們針對這個場景向分布式系統上的延伸,如下圖所示,當單點系統進行分布式化之后,實際上是由于資源的多點分布導致分布式事務場景的產生。
資源主導「服務依賴主導」
下圖展示的服務依賴主導,畢竟業務架構通常是比較復雜的,只需要一個服務訪問一份數據資源的服務還是比較少的,隨著SOA服務化理念的加深,特別是微服務的大規模應用,導致服務依賴非常復雜,因此這種分布式事務的場景完全由服務依賴所主導
服務依賴主導「混合主導」
即數據資源分布+服務依賴主導,這里需要注意的是,不是說傳統數據庫和分布式系統就是涇渭分明的,在一個成熟的業務架構下,一會存在DB和分布式系統混用的情況。如下所示
?
分布式事務的分類
分布式事務從實現方案的類型上分為「剛性事務」和「柔性事務」。
剛性事務通常并不需要業務進行改造,實現的是強一致性,強一致性的同步阻塞導致服務并發上不去,比較適合短的事務。而柔性事務通常業務會參與進行改造,事務基本都是異步的,因此實現的是最終一致性,高并發,比較適合長事務。
換個角度看,結合CAP中的內容,剛性事務對應著分布式系統中遵循ACID的CA系統;柔性事務對應著分布式系統中遵循BASE的CP系統。
有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的啥?分布式啥?啥事务?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双12压测引出的线上Full GC排查
- 下一篇: System.Object 是 .NET