分佈式事務 - 二階段提交

CAP無法同時滿足的原因

通過這個場景來證明 CAP(C 一致性、A 可用性、P 分區容錯性)無法同時滿足,

用戶下單,庫存減 1,訂單加 1,用戶積分增加。

P 分區容錯性:網絡是不可靠的,需要容忍網絡帶來的一些問題,所以要麼保證 A 捨棄 C,要麼保證 C 捨棄 A。

在高可用且保證用戶體驗的情況下,一定時間內必須給用戶響應,即保證 CP 的情況下需要捨棄 A 高可用。

如果庫存扣減成功,但在訂單增加的時候卡住了,爲了保證數據的一致性,需要等待重試,直到這 2 個數據統一以後,才能正常的往下運行。這個時候保證了 CP,但高可用無法保證,因爲在當前訂單服務卡死的情況下,沒辦法在限定的時間之內給用戶做出響應。

如何保證AP?

加入庫存成功了,訂單服務出現了問題,如果保證 AP,則設置一個超時時間,比如在 2 秒內必須給用戶返回響應 ,哪怕是異常響應(比如當前系統繁忙,請稍後重試),而不是讓用戶等着。

如果要保證數據一致性的話,用戶只能轉圈等待,但爲了保證用戶體驗和高可用,就需要在指定時間之內給出響應,這個時候就保證了 AP,C 一致性就無法保證了,因爲超出了 2 秒之後做出響應的時候,這時數據還沒有完全達到一致性的狀態。

這也是爲什麼 CAP 不能同時存在的原因,在分佈式系統中 P 是必須保證的,因爲沒有 P 網絡的話,就不能稱之爲分佈式系統,所以要麼保證 CP 要麼保證 AP。

在 CAP 理論之下,誕生了 Base 理論。

Base理論

Base 理論有 3 個狀態:基本可用、軟狀態、最終一致性,對一致性和可用性權衡的結果,源於大規模互聯網系統分佈式實踐的總結,也是基於 CAP 定理演化而來的。

Base 的一個核心思想:即使無法做到強一致性(數據必須同步),但每個應用都可以根據自身特點採用適當的方式來達到最終一致性。

基本可用:在整個分佈式系統中出現了不可預知的故障,允許喪失一部分系統的可用性的。

比如雙 11,用戶下單,在高併發的情況下,有些服務是沒有辦法用的,庫存服務和訂單服務需要保證能夠正常使用,因爲是核心業務,但是用戶積分並不是核心業務,允許用戶系統喪失一部分系統的可用性。

因爲網絡問題或併發量太高了,不需要立刻把積分加上,可以允許一段時間之後再加上,用戶看到的是老的數據而不是最新的數據。

所以也就提出了軟狀態和基本可用的概念,核心業務要保證高可用,軟狀態是允許用戶積分系統基本可用,待一定時間之後同步最新數據。

分佈式系統出現了不可預知的系統故障,允許損失一部分可用性,但絕不等於系統不可用。

1、響應時間上損失,比如正常情況下需要 0.5 秒響應,但是如果出現了故障響應時間達到了 1-2 秒。

2、系統功能的損失,正常情況下,消費者可順利完成訂單,但在節假日或大促期間,爲了保證服務器的穩定,消費者可能會被引導到一個降級頁面。

軟狀態就是一種中間狀態,數據允許存在中間狀態,並認爲該中間狀態的存在不會影響整個系統的可用性,即允許系統不同節點數據副本之間同步過程存在延遲。

庫存和訂單需要保證一致性,但是用戶積分需要一段時間同步之後,才能達到數據最終一致性。

最終一致性,是所有數據副本通過一段時間同步之後,最終達到的一致性狀態,而不是實時同步(強一致性)。

在過了流量高峯以後,經過一段時間的同步,保持各服務數據的一致。

Base 理論是基於 CAP 理論誕生的,很多分佈式事務的解決方案是基於 Base 理論誕生的。

2PC兩階段提交協議

將整個事務分爲 2 個階段:準備階段和提交、回滾階段。

和相親對象喫飯,飯店老闆規定喫飯必須先付錢,男方提出 AA,即兩人只要有一個人不願意交錢,就不能喫飯。

準備階段:老闆要求男方付款,男方把錢交了,要求女方付款,女方把錢交了。

提交階段:老闆出餐,兩人喫飯。

如果女生不同意,相當於兩人在準備階段,男方把錢交了,女方不交錢,在提交階段做回滾操作,回滾的時候,老闆需要把男方的錢退回,然後兩人離開。

這就是一個分佈式事務的場景,男女雙方只要有一方拒絕付款,老闆就不出餐並且會把收到的錢原路返回。

分佈式事務的角色

一個是事務的管理器,一個是事務參與者,事務管理器是老闆,男女雙方是事務的參與者。

由管理器來抉擇整個分佈式事務,事務管理器決策整個分佈式事務在計算機中關係型數據庫支持的兩階段提交協議的過程。

在準備階段,事務管理器會向每個參與者發送準備消息,每個事務參與者(比如數據庫)參與執行本地事務,(對應着男方交錢、女方交錢),會寫入日誌數據,這個日誌是 undolog 和 redolog,此時事務並沒有真正提交,只是一個準備階段。

undolog 是記錄修改前的數據,數據是用於數據回滾的;redolog 是記錄修改後的數據,比如有 1000 塊錢交 100 喫飯還剩 900,undolog 記錄 1000,redolog 記錄 900。

在提交階段,如果事務管理器收到了提交失敗或超時的消息,則直接給每個參與者發送回滾的消息,否則就是整體提交。

參與者根據事務管理者的指令來執行提交或回滾的操作,並且在執行之後要釋放整個事務中所使用的資源,也就是說需要把日誌給刪掉。

在準備階段,事務管理器發送消息,讓男女雙方交錢,如果分別把錢交了,再分別回給事務管理器一個狀態:錢交了。

第二個階段就是提交階段:老闆出餐,雙方喫飯。

如果女方回絕:我不喫這飯了 。其中有一個事務參與者返回失敗的消息給事務管理者,最終進行回滾,即把收到的錢退回。

訂單、庫存的場景

TM(事務管理器)發送準備消息給訂單服務和庫存服務,訂單服務開始事務、執行本地事務,本地事務提交,此時訂單加 1 了,給 TM 返回一個執行成功的消息;再調用庫存,庫存開始事務、執行本地事務、本地事務提交,給 TM 返回執行成功,此時 TM 整體提交。

如果訂單創建失敗了,告訴 TM 執行失敗, TM 通知兩方整體回滾,庫存減 1 的數據會根據記錄的 undolog 日誌,把減 1 的數據回滾到之前的狀態,假如之前是 100,減 1 之後是 99,就回滾到 100 的狀態。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/A7T-_XtP0CkzSgsmE_VDuw