02.27 「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

按:交易系統一般以訂單為核心,狀態機做流程驅動。最近十年我們對訂單的看法是正向流程承載的單據,今天有一個新觀點——交易契約。交易的業務狀態及流轉、高可用、零資損等,是其主要的挑戰。訂單的海量存儲是一個普遍的挑戰,因為每天都會產生、生命週期從一天至一年不等,冷熱數據差異明顯。本文來自有贊交易中心、王爺的分享。

有贊訂單管理主要承接有贊所有訂單搜索及詳情展示功能,系統隨著業務的不斷髮展經歷了多次飛昇之路。下面簡單介紹下有贊訂單管理系統的三生三世與“十面埋伏”。

第一世:凡人飛昇小仙之路-分庫分表

隨著業務發展,單庫單表所能承載的數據量侷限性越發嚴重。歷劫:單庫單表數據量承載侷限渡劫:分庫分表分庫分表的維度針對系統買賣家查詢的需求,分片鍵為買家 id 和店鋪 id,其餘訂單擴展信息表屬於數據組裝信息,均以店鋪 id 為分片鍵。結果:分庫分表後,數據業務量的承載質的提升。

第二世:小仙飛昇上仙之路-引入ES搜索引擎

隨著業務搜索維度的不斷添加,使得跨表查詢需求越來越多,系統的慢查不斷報出,為此引入了 ES 搜索引擎。歷劫:跨表查詢越來越多,系統慢查頻頻報出

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

渡劫:引入 ES 搜索引擎ElasticSearch 是一個基於 Lucene 的搜索服務器,這裡主要是通過將訂單主表及輔表的索引字段同步到ES裡,這些每張表單獨的索引字段,彙總成一個聯合索引,來實現多個表的跨表搜索。結果:目前運行良好,統計的檢索需求響應時間均值 20ms 以內,對於命中緩存的在 1ms 以內返回。由於多表聯查的流量都進了 ES,所以系統慢查被清0。

兩個問題需要注意下:

1. 單 Type 與多 Type 的選擇ES 裡使用文檔存儲,一個 Index 可以理解為一個庫,一個 Type 可以理解為一張表,那麼訂單及其擴展信息面臨使用單 Type 還是多 Type 的抉擇。 多 Type 優點: 可以做到索引字段與表結構一一對應, 數據同步隔離單一,直觀簡單。多 Type 缺點:獲取數據時候需要一次數據聚合,比如一次跨 5 張表索引聯查,需要先分別取出 5 張表的數據,然後做一次交集。性能會有影響。類似於 DB 的跨表聯查,而且當數據做冷熱隔離,數據拆分時候,多 Type 的拆分和維護成本反而更高。單 Type 優點:可以做到數據一次請求即可將目標信息全量返回,一個 Type 的數據拆分冷熱隔離維護成本可控。單 Type 缺點:數據同步成本高一些,要做好數據聚合一致性問題。 結合業務需求場景,這裡採用的單 Type 方案。如下圖所示。

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

2. 索引字段數量控制

由於訂單及其擴展信息字段較多,將這些信息全量同步到 ES 會導致索引字段過多,索引文件也會隨之過大,檢索效率會受到影響。所以這裡採用了將訂單及其擴展信息中強搜索需求的索引字段同步了進來,並沒有做全量所有字段同步。

第三世:上仙飛昇上神之路-引入 Hbase

隨著業務的不斷髮展,對系統性能的要求的不斷提高,我們發現雖然數據檢索的效率很高,但是數據組裝的效率令人擔憂,由於需要從 ES 中獲取的訂單號列表到各個擴展表去獲取具體信息,也就是一次完整的訂單列表拉取時間=數據檢索時間+數據組裝時間,而數據組裝就算是批量獲取,也要去取 N(假如有 N 張訂單擴展表)次,即使並行去取也不夠高效,上文討論過沒有將訂單的所有信息全部同步到ES的原因,這樣一次完整的訂單拉取時間=數據檢索時間。歷劫:數據組裝效率低下

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

渡劫:引入 Hbase 來為詳情數據組裝 Hbase 是一個高可靠性、高性能、面向列、可伸縮的分佈式存儲系統。可以通過 MapReduce 來處理 HBase 中的海量數據。

這裡將訂單基本信息及其強依賴的擴展信息全量導入 Hbase,其中歷史數據採用 BulkLoad 導入,增量數據採用消息同步寫入,以訂單號為 rowKey 為訂單號,這樣通過一次請求,將該訂單的基本信息及擴展信息一次性取出。

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

結果:訂單管理架構被抽象成了 DB+ES+HBASE 的三層架構(如下圖所示),DB 作為數據寫入源頭,ES 負責搜索請求的 parser 解析及基本數據返回(即 Es 返回字段即可滿足需求的場景),而 Hbase 作為訂單詳情詳細信息的組裝載體,兩者配合提升整個訂單列表搜索和詳情組裝的性能。同時 Hbase 的數據源也可以被複用到訂單導出,數據統計等離線需求上。

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

寫到這裡可能很多朋友都看出,實現這一切還有一個非常重要的劫需要去渡。那就是數據同步的實時性和一致性。感興趣的話後續文章可以重點寫寫數據同步以及踩過的坑和破局之道,這裡簡單拋磚引玉下。

歷劫:數據同步的實時性與一致性

渡劫:鏈路白盒+冪等性保障

1. 鏈路白盒:整個同步鏈路是先監聽 binlog 然後同步到消息隊列中,業務消費處理同步到 Es 和 Hbase,可以將整個同步鏈路監控起來,比如一個消息 binlogTime->addMqTime->processTime->addEsOrHbaseTime,這個差值其實就是實時性的一個指標。一旦整個同步鏈路的白盒搭建好,那麼對應的報警監控,失敗重試補償就都可以跟進配套完成。保證數據的完整性與實時性。同步鏈路及同步監控如下圖所示。

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

「交易架構day6」有贊訂單交易系統演進之路:如何存儲海量訂單

2. 冪等性保障:如果不能保證業務消費的冪等性,那麼消息的亂序,數據的重放監控補償等等就會很被動。這裡簡單提供幾種冪等思路:

  • 業務樂觀鎖字段:比如訂單狀態的流轉,應該是一個正向更新,即後一次更新的 state 一定大於等於前一次。
  • version 字段:表設計時候留一個 version 字段,每次數據庫更新都會將該字段加 1,作為樂觀鎖依據。
  • sonwflake 算法:可以根據業務需要定製自己的 snowflake 算法,比如毫秒級時間戳+binlog 變更自增號
  • 消息有序:對於一些強依賴消息有序或者業務樂觀鎖不好設定時候,消息端的有序變得尤為重要,可以給根據業務唯一鍵(如訂單號)進行機器取模,保證同一筆訂單的變更數據會被推送到同一臺機器上消費。 其中業務樂觀鎖使用簡單高效,無需額外存儲樂觀鎖字段,而消息強有序每次需要使用取模計算,性能多少會有些影響,不過經過壓測數據顯示性能差別不大,這邊採用業務樂觀鎖+消息有序共用的方案。目前線上運行良好。

=>更多交易架構系列請參考:《中國互聯網業務研發體系架構指南》(更中)

喜歡關於程序猿成長的內容,可關注我的頭條號 “軟件真理與光”!


分享到:


相關文章: