摘要:分布式事務與云原生技術有很強的關聯,可以幫助云原生應用程式實作高效的分布式事務處理,
本文分享自華為云社區《理解和學習事務,讓你更好地融入云原生時代》,作者: breakDawn,
隨著云原生的概念越來越火,服務的架構應該如何發展和演進,成為很多程式員關心的話題,大名鼎鼎的《深入理解java虛擬機》一書作者于21年推出了新作《鳳凰架構》,從這本書中可以看到當前時下很多最新的技識訓者理念,
因此本文以及后續都將持續沉淀發布這本書的學習筆記和思考,也歡迎購買該書進行詳細學習,或者關注后續的學習筆記內容發布,了解精華內容和總結思考,
事務處理
事務有四個經典的特性ACID:
- 原子性 (Atomicity):事務中的所有操作都必須是原子的,即不可分割或撤銷的,在一個事務執行期間,所有的操作都必須同時成功或同時失敗,不存在中間狀態,
- 一致性 (Consistency):事務執行的結果必須保證資料庫的一致性,即資料庫中的資料必須在事務開始和結束時保持一致,
- 隔離性 (Isolation):事務之間的操作相互隔離,即一個事務的操作不會受到其他事務的影響,
- 可用性 (Availability):事務執行期間資料庫必須保持可用,即可以在任何時候進行訪問和修改,
這四個特性ACID中, C其實是目的, AID是手段,只靠內部(單資料源)可以用AID實作C,但是外部(多資料源)的情況下沒法用AID保證C,
1本地事務
本地事務是一種最基礎的事務解決方案,適用單個服務使用單個資料源的場景,(注意,對于MyISAM來說,代碼層面呼叫的rollback其實是空操作,引擎內置了事務處理,不需要代碼呼叫rollback)本地事務的實作原理來自ARIES(基于語意的恢復與隔離演算法),
1.1 本地事務如何實作原子性和持久性
本地事務中, 寫入磁盤的程序可能不是原子的,是會崩潰的,因此要考慮2個例外情況:
- 未提交事務(呼叫事務的應用層代碼未回傳成功),資料還沒改完,寫了一半崩潰了,導致資料不一致,非原子性
- 已提交事務(呼叫事務的應用層代碼已經反悔了),但是實際磁盤內容還沒寫就崩了,導致資料完全沒變化,非持久性,
解決方式:
引入commit log, 即將事務對資料的修改先寫入commit log,寫入成功代表事務成功,寫入完成后再寫磁盤,如果中途崩潰了就重新寫入,等同于熟知的redo-log!
這也是為什么redo-log中是針對某個物理塊的修改,目的就是能正確重新,不用考慮我寫到哪個位置了,直接全部重刷即可,
但是這樣性能太慢,希望能在事務提交完成前提前寫入磁盤,但是提前寫的話可能會非原子,這時候就可以引入 undolog, 即觸發回滾時,可以講已操作的資料進行undo回滾操作,這也是為什么undo-log記錄的是一條條不可重復執行的陳述句,
文中還提了2個特征:
- NO-FORCE:事務提交后,不強求立刻全部寫入磁盤,可以延遲(commit-log,有這的存在就不著急了);
- STEAL:事務提交前,可以先寫入一部分資料(undo-log)
1.2 本地事務如何實作隔離性
隔離性主要就是依賴 資料庫鎖和資料庫隔離級別實作,書中用作者自己的話簡述了一遍從可串行化 到可重復讀到讀已提交到讀未提交的演變程序和實作原理, 也提了以下MVCC等內容,
看完后感覺和我這篇文章講的內容基本對的上:將資料庫9種鎖、3種讀、4種隔離級別一次性串聯起來,用15張圖呈現背后資料庫事務背后的并發原理
里面有幾句比較重要的話:
- MYSQL/Innodb的“可重復讀級別”只能在“只讀”事務中解決幻讀問題,但是讀寫事務還是會幻讀;
- 讀未提交仍然是包含了寫鎖的;
- MVCC只是針對讀+寫的場景做了優化, 如果是寫+寫是沒法優化的,只能用鎖;
- 范圍鎖不是指對范圍內的每一條記錄加鎖, 而是整個范圍內甚至都不能做插入了,即包含了間隙的鎖,
2 全域事務
這里的全域事務指的是 單個服務 使用多個資料源,核心在于是單個服務,不涉及多服務之間的關聯, 視角只有單服務,
XA介面是雙向的,能在一個事務管理器和多個資源管理器之間形成通信橋梁,協調多個資料源的一致動作,實作全域事務的統一提交和回滾,Java基于XA介面衍生出的API叫做JTA(javax.transaction.TrancsactionManager和 XAResource),
注意對于全域事務,呼叫XA的應用者是可以不需要額外處理的,XA會協助做好以下全域事務的回應操作,
2.1 2PC協議(兩階段提交)
準備階段
資料源將需要做的事務操作記錄在redolog中,完成了持久化,并仍舊持有鎖,保持隔離性
提交階段
協調者收到了所有資料源的回應后, 給所有資料源發送commit指令,如果有任一失敗或者超時,則發送abort回滾指令,
2PC的缺點:
- 協調者單點問題:協調者掛了其他的資料源都會一直在持有鎖的情況下等待;
- 準備階段的性能問題:整個程序將被最慢的那個資料源所拖累,包括如果連接超時也會影響,導致多余的回滾操作;
- 一致性風險:指令丟失、資料源機器崩潰且無法恢復(FLP不可能原理:如果岱機后無法恢復,那么沒有任何分布式協議可以達成一致性),
2.2 3PC協議
為了解決上面的單點問題和 準備階段的性能問題,引入3PC協議,將準備階段擴展為:
CanCommit詢問階段
這個階段就是為了確認各機器是否還是正常的,如果經過確認都是正常負載的狀態,再下發事務操作,這樣就能避免被網路超時、不良負載拖累的風險,
PreCommit預提交階段
和之前一樣,下發事務后各資料源寫入重做日志,
DoCommit階段
這個程序有一個優化, 如果協調者掛了, 資料源遲遲無法收到,就會默認進行事務提交(注意并非默認回滾),3PC仍然存在網路問題導致的一致性問題,
3 共享事務
書里說這個不常用,不寫了,類似于提供共享的資料連接給不同行程使用,使用同一個事務邏輯
4 分布式事務
4.1 CAP理論
- C一致性: 各節點同一時刻回應結果一致(資料一致)
- A可用性: 各節點隨時隨地都要能正常回應,不能存在延遲或者阻塞的情況(快速回應)
- P磁區容忍性:某個節點掛了,其他節點能代替服務
科學家證明CAP只能同時滿足2個
- 放棄磁區容忍性P: 意味著分布式系統不成立,這種情況只有類似于Oracle RAC這種資料通過磁盤共享的情況, 雖然是多個實體,但不算分布式, 基本是分布式系統一定都會包含P,否則沒有考慮分布式事務的意義
- 放棄可用性A: 這樣可能因為資料同步程序的延遲或者超時,造成系統長時間不可用, 這是不能容忍的
- 放棄一致性C: 資料有短暫不一致的回應, 放棄C是當前分布式系統的主流選擇, 一般都是允許資料在中間程序出錯, 但允許在輸出時能夠修正古來, 因此我們放棄了強一致性,追求“最終一致性”
4.2 BASE(可靠性佇列)
BASE指 基本可用性 + 柔性事務 + 最終一致性, 或者叫做最大努力交付
實作原理是引入一個訊息佇列,當某個事務動作發生例外時, 在輪詢階段不斷重試,直到成功,
要求滿足冪等性,可靠性事件佇列只要第一步完成了,后續就沒有失敗回滾的概念,只許成功,不許失敗,
4.3 TCC事務
TCC用于解決BASE中無法解決的隔離性問題,因為BASE不允許失敗,一定會執行,如果涉及了超售等問題將無法解決,
- Try: 嘗試執行階段, 會先進行業務可執行的檢查,并提前預留好需要扣除的資源(類似于凍結那一塊資源,但沒有實際去扣);
- Confirm:執行階段,這個程序不再做任何檢查,直接執行,如果網路出錯等緣故則一直重試,符合冪等;
- Cancel:執行完成,釋放try階段中預留的業務資源,也要符合冪等,
和2PC很類似,但TCC是在用戶應用代碼層面實作的,業務侵入性很高, 而2PC是基礎設施層面提供的,
4.4 SAGA事務
TCC中的缺點在于 try階段和cancel階段依賴用戶代碼實作,但如果你的業務不支持這種操作就麻煩了,比如扣款動作是某個銀行做的, 他不支持預扣款的功能,
SAGA會把事務拆成很多個小事務T,按順序執行, 并根據情況給事務T失敗時選擇是繼續重試T, 還是用補償事務C來替代重試
這樣像銀行無法預扣款也無法撤銷轉賬的問題,可以改成自己系統來做中間者做轉賬操作,也要引入SAGAlog機制避免長串事務執行程序中崩潰,
總結
其實學習本文時,更重要的是思考為什么要學習這么多的事務概念和原理,在云原生時代,
像華為云提供的很多資料庫型別的云服務也都支持了分布式事務的能力,例如
-
華為云RDS分布式事務:
基于2PC原理實作的MSDTC分布式事務協調器 -
華為云DDM事務模型:
這里面的分布式事務模塊基于 MySQL XA 協議實作,XA 協議是對 2PC(Two Phase Commit) 事務模型的一種實作, -
華為云DWS分布式事務:
基于強一致性的CSN事務機制,使用GaussDB分布式框架下的一個組件GTM以及從中獲取到的CSN值來處理事務,
畢竟云原生應用程式通常由多個微服務組成,因此需要在微服務之間進行通信,并保證事務的一致性,在這種情況下,就需要一種適用業務場景的分布式事務解決方案,比如TCC可以在微服務之間實作分布式事務的ACID特性,而且相對于其他方案,TCC更輕量級,對性能影響更小,但其他方案也有各自的適應場景,
因此,分布式事務與云原生技術有很強的關聯,可以幫助云原生應用程式實作高效的分布式事務處理,當使用某個關系型資料庫產品時,關注他們的分布式事務處理能力并分析是否適合自己當前的業務場景,是非常重要的,也是本書該章節值得學習的一個理由,
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/551927.html
標籤:其他
上一篇:當Serverless遇到Regionless:現狀與挑戰
下一篇:返回列表
