强势解析 eBay BASE 模式、去哪儿及蘑菇街分布式架构
互聯網行業是大勢所趨,從招聘工資水平即可看出,那么如何提升自我技能,滿足互聯網行業技能要求?需要以目標為導向,進行技能提升。
本文主要針對分布式系統設計、架構(數據一致性)做了分析,祝各位早日走上屬于自己的"成金之路"。
?
目錄:
問題分析
概念解讀
Most?Simple原理解讀
eBey、去哪兒、蘑菇街分布式事務案例分析
參考資料
?
1.問題解析?
要想做架構,必須識別出問題,即是誰的問題,什么問題。
明顯的,分布式架構解決的是高并發的問題。
高并發下服務高可用和數據一致性問題;當規模規模較小時,單庫 HA 即可滿足請求,當業務規模持續增加,單庫已經無法滿足業務需求,業界主流做法,是對業務進行分表、分庫,那么原來的有些業務,現在則要在一個事務中,保證兩個庫同時操作成功或操作不成功(一個庫成功,一個庫失敗,要么重新嘗試失敗庫操作直到成功,要么回滾成功庫)。
隨之而來的問題既是如何保證分庫時業務操作的數據一致性。理解分布式架構、分布式系統數據一致性的問題、起源是第一步。
這里多啰嗦一點,分庫后,每個庫可以采取不同的語言,以時下很流行的微服務向外提供服務;但是業務量不大的情況下,使用微服務到增加了復雜性及技術成本。明白技術的起源,針對不同的業務量,采取適當的架構、以最恰當的方式承載業務,是架構師必須具備的能力。
?
2.常見概念解讀
關系型數據庫通常具有 ACID 特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
Base (basically?available,?soft?state,?eventually?consistent):一種?Acid?的替代方案,BASE?的可用性是通過支持局部故障而不是系統全局故障來實現的。化學理論中 ACID 是酸、Base 恰好是堿。
CAP 定律:在分布式系統中,同時滿足" CAP 定律"中的"一致性"、"可用性"和"分區容錯性"三者是不可能的。
強一致:當更新操作完成之后,任何多個后續進程或者線程的訪問都會返回最新的更新過的值。這種是對用戶最友好的,就是用戶上一次寫什么,下一次就保證能讀到什么。根據?CAP?理論,這種實現需要犧牲可用性,常見的 RDBMS。
弱一致性:系統并不保證續進程或者線程的訪問都會返回最新的更新過的值。系統在數據寫入成功之后,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之后可以讀到。
最終一致性:弱一致性的特定形式。系統保證在沒有后續更新的前提下,系統最終返回上一次更新操作的值。在沒有故障發生的前提下,不一致窗口的時間主要受通信延遲,系統負載和復制副本的個數影響。DNS?是一個典型的最終一致性系統。
為保證可用性,互聯網分布式架構將強一致性需求轉換成最終一致性的需求,并通過系統執行冪等性的保證,保證數據的最終一致性。
?
※冪等性 (Idempotence):分布式架構的基石,即同一個操作無論請求多少次,其結果都相同。
典型的是HTTP,
Methods?can?also?have?the?property?of?"idempotence"?in?that
?(aside?from?error?or?expiration?issues)?the?side-effects?of?N?>?0
?identical?requests?is?the?same?as?for?a?single?request.
?
每個概念實際所解決的是人遇到的某個特定的問題,發現其背后所代表的問題,是理解分布式架構、分布式系統數據一致性第二步。
?
3.Most?Simple原理解讀
假設有一個從賬戶取錢的遠程 API(可以是 HTTP 的,也可以不是),我們暫時用類函數的方式記為:
bool?withdraw(account_id,?amount)
withdraw 的語義是從 account_id 對應的賬戶中扣除 amount 數額的錢;如果扣除成功則返回 true,賬戶余額減少 amount;如果扣除失敗則返回 false,賬戶余額不變。
值得注意的是:和本地環境相比,我們不能輕易假設環境的可靠性。
一種典型的場景是 withdraw 請求已經被服務器端正確處理,但服務器端的返回結果由于網絡等原因被掉丟了,導致客戶端無法得知處理結果。
如果是在網頁上,一些不恰當的設計可能會使用戶認為上一次操作失敗了,然后刷新頁面,這就導致了 withdraw 被調用兩次,賬戶也被多扣了一次錢。如圖1所示:
一種更輕量級的解決方案是冪等設計。我們可以通過一些技巧把 withdraw 變成冪等的,比如:
int?create_ticket()?
bool?idempotent_withdraw(ticket_id,?account_id,?amount)
create_ticket 的語義是獲取一個服務器端生成的唯一的處理號 ticket_id,它將用于標識后續的操作。idempotent_withdraw和withdraw 的區別在于關聯了一個 ticket_id,一個 ticket_id 表示的操作至多只會被處理一次,每次調用都將返回第一次調用時的處理結果。這樣,idempotent_withdraw 就符合冪等性了,客戶端就可以放心地多次調用。
基于冪等性的解決方案中一個完整的取錢流程被分解成了兩個步驟:
調用create_ticket()獲取ticket_id;
調用idempotent_withdraw(ticket_id,?account_id,?amount)。
雖然 create_ticket 不是冪等的,但在這種設計下,它對系統狀態的影響可以忽略,加上 idempotent_withdraw 是冪等的,所以任何一步由于網絡等原因失敗或超時,客戶端都可以重試,直到獲得結果。如圖所示:
和分布式事務相比,冪等設計的優勢在于它的輕量級,容易適應異構環境,以及性能和可用性方面。在某些性能要求比較高的應用,冪等設計往往是唯一的選擇。
冪等性是分布式架構、分布式系統數據一致性的底層基本原理,理解這一步,是走上"成金之路"的關鍵。
?
4.案例分析
eBay 經典的 BASE 模式
一個最常見的場景,如果產生了一筆交易,需要在交易表增加記錄,同時還要修改用戶表的金額。這兩個表屬于不同的庫及遠程服務,所以就涉及到分布式事務一致性的問題。
核心思想是用兩個事務來保證一致性,同時用異步保證了可用性:一個事務處理主要操作"增加交易表記錄"與異步消息構建,另外一個事務用來處理構建的異步消息;第一個事務即處理主要業務又記錄次要業務,同時還能快速返回,保證了高可用性,第二個事務則用來保證數據的一致性。(即將 buyer 和 seller 表更新的處理轉為"線下"處理,消息日志可以存儲到本地文本、數據庫或消息隊列,再通過業務規則自動或人工發起重試。人工重試更多的是應用于支付場景,通過對賬系統對事后問題的處理,類似與淘寶雙11重復支付后續退款)。
一個經典的解決方法,將主要修改操作以及更新用戶表的"異步消息"放在一個本地事務來完成。同時為了達到多次重試的冪等性,避免重復消費用戶表消息帶來的問題,增加一個更新記錄表?updates_applied?來記錄已經處理過的消息。
在第一事務中,通過本地的數據庫的事務保障,保證"增加交易表記錄"、"增加兩條異步消息隊列記錄(一條處理 buyer 表、一條處理 seller 表)",同時成功或同時失敗。
在第二事務中,分別讀出消息隊列(但不刪除),通過判斷更新記錄表?updates_applied?來檢測相關消息是否被執行,如沒執行,則執行相關業務邏輯(保證冪等性,保證即使執行過程中異常,重復執行沒有任何問題),執行完所有消息后然后增加一條操作記錄到 updates_applied,事務到此結束。用事務保證兩個異步消息執行及 updates_applied 的一致性操作(又稱為分布式事務框架)。最后刪除隊列。
去哪兒網分布式事務方案
優先使用異步方案,原理和"a.eBay 經典的 BASE 模式"類似,對業務邏輯處理不能保證"冪等性"的,增加去重表(即 a 中的 updates_applied) 來處理
對于不適合異步消息處理的業務,如 A、B、C 三方需要同步處理才能返回:在 A、B、C 三個庫中分別維護一個事務記錄表 recorda/recordb/recordc,當 A、B、C 業務事務處理完,將結果存到對應的 recordx 中,由一個中心服務對比查詢三方的事物記錄表,有如下兩種處理方式:
第一種:A、B成功,C失敗了,重試C,知道C成功;
第二種:C不可能成功時,回滾A、B,如C為扣庫存,當庫存為0時,則不能成功(不考慮補庫存)。
另,這種 recordx 表由 RPC 框架層進行維護,對業務是透明的。
蘑菇街交易創建過程
場景:將下單功能拆分為12個子業務(見參考資料b),對于非實時、非強一致性的關聯業務,使用" eBay 經典的 BASE 模式"思想,第一個本地事務執行成功后,以發消息通知、關聯事務異步化執行方案,來避免 a 中第二個事務的"分布式事務框架"對業務帶來的侵入和復雜性,具體方案是基于DB事件變化通知給 MQ,而 MQ 消費者通過 ACK,保證消息一定消費成功,完成強一致性(消息可能會被重發,所以消息消費方要保證冪等性)。
而對要求同步做、強一致性要求的場景(和 b 的 ii 相同場景),如優惠券和優惠券減庫存:可以引入"a.eBay經典的 BASE 模式"的第二個事務(分布式事務框架)來處理,但是復雜性會急劇上升;
另一種方式是創建一個不可見訂單,然后在同步調用鎖券和扣減庫存時,針對調用異常(失敗或者超時),發出廢單消息到 MQ。如果消息發送失敗,本地會做時間階梯式的異步重試;優惠券系統和庫存系統收到消息后,會進行判斷是否需要做業務回滾,這樣就準實時地保證了多個本地事務的最終一致性。
根據業務進行不同的方案處理,解決了分布式架構、分布式系統的數據一致性問題。
?
?
整體來說,蘑菇街的案例可遷移性強,可移植性好,可以嘗試模擬下實際場景,駕馭分布式架構、分布式系統數據一致性方案,祝大家早日走上"成金之路"。
?
5.參考資料
a.冪等性
http://www.cnblogs.com/weidagang2046/archive/2011/06/04/idempotence.html?
b.架構案例詳細
http://weibo.com/ttarticle/p/show?id=2309403965965003062676?
c.http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistenc
作者:成金之路
鏈接:http://www.cnblogs.com/uttu/p/6553307.html
本文已獲得作者成金之路獨家授權,轉載請標明作者及出處。
內容轉載自公眾號
51CTO博客 了解更多贊賞
總結
以上是生活随笔為你收集整理的强势解析 eBay BASE 模式、去哪儿及蘑菇街分布式架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: visual studio 2017发布
- 下一篇: 使用 Angular