庫存系統實現

前言

最近在重構之前系統中的庫存處理邏輯。 老的系統中庫存處理邏輯只是一個類裏面的幾個方法,同時是直連DB操作,有緩存處理,但是在數據一致性保障上並沒有特別的可靠。 隨着運營投入的越來越多,新的運營策略在產品表現上會出現大庫存情況,比如引入package的方式,這樣原有的庫存處理邏輯的QPS就需要變爲百倍了,在高峯期對於數據庫系統的寫QPS是很大的壓力,同時系統不能簡單的通過機器擴容或者橫向擴展解決,所以需要將庫存處理邏輯單獨到獨立的服務系統中進行解決。

業界方案

阿里在數據一致性的處理上採用了數據庫方案,當然爲處理高併發寫入,阿里有能力在數據庫角度進行了優化,可以支持高併發寫入和事務控制,一般公司不具備這樣的技術能力,需要在業務層進行顯示控制。

系統關鍵點

考慮基於DB解決數據一致性問題,首先要解決單點瓶頸和數據過多造成的數據傾斜問題。

同時系統需要考慮單元化場景下的庫存扣減邏輯,核心邏輯在於庫存扣減是否和用戶產生直接關係。

事務控制

由於不具備數據庫層面的高併發事務控制,需要在系統層面進行實現。

採用樂觀鎖 整個加鎖時間

start transaction
lock budget record and get its value
subtract budget record by
insert business orders...
commit 

通過sql層面更新取代先讀後更新邏輯。

SQL優化批量處理 SQL組合在一起,和DB一次交互,更新語句保持條件更新,保證更新後餘額大於等於0。 SQL添加commit_on_success(減少commit請求網絡交互),target_affect_row 1標籤。

系統分片

單個數據庫無法支撐高併發寫入,考慮“桶拆分”,根據userId進行分桶,子桶配額不足時,路由到主桶。 主桶和子桶按比例分配,子桶適合時機回收。

設置分桶閾值,自動分桶,同時基於日誌流水(定時任務)進行分桶合併,異步將庫存分桶合併到主桶。可降低更新頻率,只在合併時發生更新一次,通過定時任務消除分桶碎片,定時任務進行補償。

分佈式事務

庫存扣減設計到下游多個服務聚合,需要保證事務一致性,在一個下游服務失敗後可以主動感知。

  • 兩階段提交:方案過於悲觀,放棄。
  • 設計基於輕消息組件,引入事件記錄,保證事件記錄和數據操作在一個DB事務中,基於消息實現事件通知,事務1失敗,進行反向扣減處理(都只是預操作),第二階段進行整體事務commit,方案需引入minibus方案。

結論

基於以上方案重構庫存系統服務,單記錄(子桶)維持在8kqps,摸高到1w+qps,32個子庫壓測達30wQPS性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章