一年前,在上一家公司接手了乙個含有訂單系統的專案,業務並不複雜,但是當時令我比較困惑的是訂單表的設計。
困惑的點主要是隨著訂單量增加,單錶的儲存能力將達到瓶頸,必然要採用分表的方案,那麼按照什麼維度拆分合適呢?
分表之後帶來的最大的挑戰是訂單查詢。如果以使用者為中心,採用userid取模,可以很方便的處理使用者查單訴求,但是對商家或產品而言,資料就比較分散,相反如果以商家或商品為中心,則使用者查單比較困難。
由於對這樣的業務沒有成熟的經驗,最後只能採取相對討巧的方案,按照自然日期分表,考慮訂單量並不大,當時是每個季度一張表,一年4張表。
為什麼說討巧?以使用者查單為例,查詢頁預設要選擇乙個季度,也就是將使用者訂單資料限制在一張表中做查詢。大多數時候使用者也只是檢視最近訂單,所以勉強可以接受。
如果使用者一定要檢視全部訂單,只能將所有訂單表union all,當時想的是至少前幾個年頭訂單表數量有限,效能問題不會太嚴重,以後再想辦法進行優化。
前幾天又想到了這個訂單表的設計問題,於是和現在的同事進行了簡單的溝通,也學到了非常寶貴的經驗。在這裡簡單記錄一下,說的不對的地方希望大家多多包涵並不吝賜教。
具體怎麼做呢?
簡單來說就是冗餘+同步+檢查。資料冗餘,非常有效的解決了資料分散的問題。將訂單落庫訂單表(暫且稱作訂單表o),訂單表按照日期分表,按天,周,月,季度或者年都可以,可根據實際業務量選擇。分表首先解決了單錶儲存的瓶頸問題。如何冗餘?以使用者查單為例,新建使用者訂單表(訂單表u-o),將userid取模分表,冗餘乙份訂單資料,u-o表中的資料可以只包含重要資訊如下單時間,數量,金額,訂單狀態等(列表頁展示)。訂單詳情資訊可以從o表中查詢。
這樣一來,使用者查單自然就只限一張表中啦。這麼簡單的問題為什麼我沒想到呢?不過這樣一來,新的問題出現了,就是如何保證這兩份(也可能多份)訂單表資料同步?雖然訂單的大部分資訊不會經常變更,但是在訂單完成之前,必然有訂單狀態的變更或使用者更新的可能。這就是我將要說的資料同步問題。
如何同步?可能大家會想到將幾份訂單資料放入事務處理,雖然事務可以有效的解決同步問題(事務一致性),但是我認為事務一方面影響了資料庫效能,另一方便增加了介面複雜性(耦合)。同事給我的方案是通過訊息元件同步,訊息在分布式系統中是非常重要的存在,可以很好的將服務解耦,而且高可用,支援高併發,響應速度快。
但是訊息同步還不能保證資料同步的絕對一致,比如訊息延時,重複,丟失等。一方面要優化訊息元件的穩定性,另一方面要做好監控。最重要的是要採取乙個主動檢查的手段。
做好資料檢查。比如啟乙個job每天凌晨進行一次前一天的資料檢查,比對所有訂單的一致性。既然採用了訊息機制,我們所有的對訂單的更新操作都是對o表進行的,因此以o表資料為準即可。
訂單系統設計 訂單號設計
三 因子分表法 唯一性 必要 每個訂單號全域性唯一代表乙個訂單 安全性 必要 訂單號不能透露訂單量 運營規模等業務資訊 資料安全性 高效能 訂單號的建立成本越低越好 擴充套件性 能夠較好的支撐後續業務發展變大帶來的分庫分表 訂單長度擴充套件等場景 不安全 訂單號能夠反映出系統的訂單量,存在業務資料外...
訂單系統架構設計
高併發下單主要包括以下幾個方面 分庫分表 多應用例項全域性唯一訂單號 資料庫連線 買家查詢訂單 賣家查詢訂單 擴容問題 業務拆分 一 分庫分表 隨著訂單量的增長,資料庫的發展主要經歷以下幾個步驟 1主 1從架構 雙主 多從架構,讀寫分離 表分割槽,提高併發 分表,提高併發 master更換ssd 分...
訂單系統設計 分頁查詢
1.2 查詢條件設計 二 技術方案 2.2 mysql es架構 三 db規範 產品設計不合理是導致深度分頁查詢的乙個重要原因,比如下圖所示的深度隨機跳頁設計方案,如果沒有特殊原因,正常情況下應避免使用。一方面,隨機跳頁實際意義有多大有待考究 另一方面,隨機性會加大後端的難度,如果隨機跳頁的頁碼很大...