- 鳳凰架構:構建可靠的大型分布式系統
- 周志明
- 1678字
- 2021-06-24 11:30:56
3.4.2 可靠事件隊列
最終一致性的概念是由eBay的系統架構師Dan Pritchett在2008年在ACM發表的論文“Base:An Acid Alternative”[1]中提出的,該論文總結了一種獨立于ACID獲得的強一致性之外的、使用BASE來達成一致性目的的途徑。BASE分別是基本可用性(Basically Available)、柔性事務(Soft State)和最終一致性(Eventually Consistent)的縮寫。BASE這種提法簡直是把數據庫科學家酷愛湊縮寫的惡趣味發揮到淋漓盡致,不過有ACID vs BASE(酸vs堿)這個朗朗上口的梗,該論文的影響力的確傳播得足夠快。在這里筆者就不多談BASE中的概念問題了,雖然調侃它是惡趣味,但這篇論文本身作為最終一致性的概念起源,并系統性地總結了一種針對分布式事務的技術手段,是非常有價值的。
我們繼續以本章的場景事例來解釋Dan Pritchett提出的“可靠事件隊列”的具體做法,目標仍然是交易過程中正確修改賬號、倉庫和商家服務中的數據,圖3-7列出了修改過程的時序圖。

圖3-7 修改過程時序圖
1)最終用戶向Fenix’s Bookstore發送交易請求:購買一本價值100元的《深入理解Java虛擬機》。
2)Fenix’s Bookstore首先應對用戶賬號扣款、商家賬號收款、庫存商品出庫這三個操作有一個出錯概率的先驗評估,根據出錯概率的大小來安排它們的操作順序,這種評估一般直接體現在程序代碼中,一些大型系統也可能會實現動態排序。譬如,根據統計,最有可能出現的交易異常是用戶購買了商品,但是不同意扣款,或者賬號余額不足;其次是倉庫發現商品庫存不夠,無法發貨;風險最低的是收款,如果到了商家收款環節,一般就不會出什么意外了。那最容易出錯的就應該最先進行,即:賬號扣款→倉庫出庫→商家收款。
3)賬號服務進行扣款業務,如扣款成功,則在自己的數據庫建立一張消息表,里面存入一條消息:“事務ID:某UUID,扣款:100元(狀態:已完成),倉庫出庫《深入理解Java虛擬機》:1本(狀態:進行中),某商家收款:100元(狀態:進行中)”。注意,這個步驟中“扣款業務”和“寫入消息”是使用同一個本地事務寫入賬號服務自己的數據庫的。
4)在系統中建立一個消息服務,定時輪詢消息表,將狀態是“進行中”的消息同時發送到庫存和商家服務節點中去(也可以串行地發,即一個成功后再發送另一個,但在我們討論的場景中沒必要)。這時候可能產生以下幾種情況。
·商家和倉庫服務都成功完成了收款和出庫工作,向用戶賬號服務器返回執行結果,用戶賬號服務把消息狀態從“進行中”更新為“已完成”。整個事務順利結束,達到最終一致性的狀態。
·商家或倉庫服務中至少有一個因網絡原因,未能收到來自用戶賬號服務的消息。此時,由于用戶賬號服務器中存儲的消息狀態一直處于“進行中”,所以消息服務器將在每次輪詢的時候持續地向未響應的服務重復發送消息。這個步驟的可重復性決定了所有被消息服務器發送的消息都必須具備冪等性,通常的設計是讓消息帶上一個唯一的事務ID,以保證一個事務中的出庫、收款動作會且只會被處理一次。
·商家或倉庫服務有某個或全部無法完成工作,譬如倉庫發現《深入理解Java虛擬機》沒有庫存了,此時,仍然是持續自動重發消息,直至操作成功(譬如補充了新庫存),或者被人工介入為止。由此可見,可靠事件隊列只要第一步業務完成了,后續就沒有失敗回滾的概念,只許成功,不許失敗。
·商家和倉庫服務成功完成了收款和出庫工作,但回復的應答消息因網絡原因丟失,此時,用戶賬號服務仍會重新發出下一條消息,但因操作具備冪等性,所以不會導致重復出庫和收款,只會導致商家、倉庫服務器重新發送一條應答消息,此過程持續自動重復直至雙方網絡通信恢復正常。
·也有一些支持分布式事務的消息框架,如RocketMQ,原生就支持分布式事務操作,這時候上述第二、四種情況也可以交由消息框架來保障。
以上這種依靠持續重試來保證可靠性的解決方案談不上是Dan Pritchett的首創或者獨創,它在計算機的其他領域中已被頻繁使用,也有了專門的名字——“最大努力交付”(Best-Effort Delivery),譬如TCP協議中未收到ACK應答自動重新發包的可靠性保障就屬于最大努力交付。而可靠事件隊列還有一種更普通的形式,被稱為“最大努力一次提交”(Best-Effort 1PC),指的是將最有可能出錯的業務以本地事務的方式完成后,采用不斷重試的方式(不限于消息系統)來促使同一個分布式事務中的其他關聯業務全部完成。
[1] 文章地址:https://queue.acm.org/detail.cfm?id=1394128。
- Linux運維之道(第3版)
- 精通Linux內核開發
- VMware Horizon View 6 Desktop Virtualization Cookbook
- 曝光:Linux企業運維實戰
- 嵌入式應用程序設計綜合教程(微課版)
- Windows Vista融會貫通
- Linux網絡內核分析與開發
- Moodle 3.x Teaching Techniques(Third Edition)
- VMware NSX Cookbook
- Windows 8實戰從入門到精通(超值版)
- Kali Linux高級滲透測試(原書第3版)
- Hands-On GPU Programming with Python and CUDA
- Linux網絡操作系統項目教程(RHEL 7.4/CentOS 7.4)(第3版)(微課版)
- Windows 8玩全不求人
- Hadoop Operations and Cluster Management Cookbook