基於Kafka消息驅動最終一致事務(一)


基本可用軟狀態最終一致事務

本用例分兩個數據庫分別是用戶庫和交易庫,不使用分布式事務,使用基於消息驅動實現基本可用軟狀態最終一致事務(BASE)。現在說明下事務邏輯演化步驟,尊從CAP原則,即分布式系統不能全部確保一致性、可用性、分區容錯性,只能三選二。文章里從一致性模式討論,例子里每次出售物品時,將一行添加到交易表中,並更新買方和賣方的數量。 使用ACID風格的事務這是強一致性事務,SQL將如圖所示。

用戶表中的購買量和出售量被認為是事務表的緩存。 在要求效率系統里,可以放寬對一致性的限制。 延遲設定買方和賣方的緩存值,使其持有的余額不會立即反映交易的結果。 這樣的做法很常見,為了效率犧牲強一致性,事實上人們經常在交易與查詢余額之間遇到這種延遲(例如ATM取款和手機通話)。是否使用弱一致性取決於如何定義運行余額。 我們現在已將更新用戶表和事務表解耦。 不使用同一事務操作兩個表一致性是不能保證的。 事實上,第一個和第二個事務之間的失敗將導致用戶表永久不一致,但如果合同規定運行總計是估計值,這不一致是可以接受。如圖所示。

如果緩存估值不能接受的話, 然后還是解耦用戶和交易更新,這要怎么辦呢? 引入持久消息隊列解決問題。 使用持久性消息有幾種選擇,然而實現消息隊列最關鍵的因素是確保消息備份持久化與數據庫位於同一資源上。 消息驅動觸發機制,添加交易記錄與消息排隊是同數據源事務,更新用戶數據與消息出隊是同數據源事務,這叫避免使用2PC提高效率。但是同一資源使系統可用性沒有提高。如圖所示。

要提高系統可用性就要將交易表和用戶表分庫處理,但是有一個問題,消息持久化在交易庫主機上,避免排隊期間的2PC,那消息在涉及用戶庫主機的事務中出現,我們仍然有一個2PC的情況。消息處理組件中的2PC的一個解決方案是什么都不做,通過將更新事務解耦為單獨的后端組件,可以保留面向客戶的組件的可用性。 在業務需求中,后端組件消息處理的可用性較低是可以接受的。2PC消息流如圖:

Message flow

Coordinator                                         Cohort
                              QUERY TO COMMIT
                -------------------------------->
                              VOTE YES/NO           prepare*/abort*
                <-------------------------------
commit*/abort*                COMMIT/ROLLBACK
                -------------------------------->
                              ACKNOWLEDGMENT        commit*/abort*
                <--------------------------------  
end

但是假設你的系統性能要求很高絕對不能接受2PC,這個問題怎么解決?首先,你需要了解冪等概念。同一操作應用一次或多次結果都相同就是冪等冪等運算是有用的,因為它們允許部分故障,因為重復應用它們不會改變系統的最終狀態。例子中尋找冪等操作是有個問題,更新操作很少是冪等的。 多次操作增加余額會導致不正確的余額。 然而即使是簡單地設置值更新操作對於操作順序也不是冪等的。 如果系統不能保證按照接收到的順序更新,系統的最終狀態將不正確。在這種余額更新下,您需要一種方法來跟蹤哪些更新已成功,哪些更新尚未完成,這種技術是記錄已處理事務標識符的表。查詢事務是否在已處理表是冪等的。如果需要,可以使用兩個獨立的事務完成此操作:一個在消息隊列中,一個在用戶數據庫上。 除非數據庫操作成功提交,否則隊列操作不會提交。 該算法現在支持部分故障,並且仍然提供事務保證而不訴諸於2PC。

 

如果不考慮購買排序情況下則有一種更簡單的技術來確保冪等更新。添加跟蹤用戶的最后銷售和購買日期,修改用戶表如圖8。更新最后銷售或購買日期小於當前消息日期的記錄數據,邏輯如圖9。這方案有個問題,假設在短時間內進行兩次購買,我們的消息系統不能保證有序入隊操作,后購買消息可能先入隊,更新操作會丟失先購買消息。您還可以嘗試單向遞增的交易ID代替最后時間

 

 用例分析基於Kafka消息驅動最終一致事務(二)

參考資料

1,http://queue.acm.org/detail.cfm?id=1394128

2,Spring Data JPA - Multiple datasources example


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM