1. 程式人生 > >(專案隨筆)關於訂單系統的思考

(專案隨筆)關於訂單系統的思考

訂單系統幾個特點:

1、歷史資訊多(每一條訂單完成後,生成一條歷史資訊,並且一般情況下,久遠的訂單資訊不回被經常檢視)

2、併發量高(特別是秒殺系統生成的訂單,每秒會有成百上千條訂單)

3、訂單id必須全域性唯一

一、分庫分表

隨著訂單量的增加,資料庫發展如下:

  • 單一的資料庫
  • 一主一從
  • 雙主多從,讀寫分離
  • 分表分庫,提高併發

已知Mysql單表效能超過千萬級別會嚴重下降,按照千萬級別來計算,假設訂單系統分為16個庫,每個庫64個表進行儲存,共1024個表,那麼,Mysql最高可以儲存百億級別的訂單。隨著儲存問題的解決,複雜度也會隨之增加,例如一下問題:

  • 多庫多表,如何保證訂單編號唯一
  • 查詢複雜度增加,怎麼解決(不知道資料具體在哪個表中)
  • 買家檢視訂單在哪裡查,賣家檢視訂單在哪裡查
  • 再大的儲存量,隨著資料的增長,總會遇到瓶頸,應該怎麼擴容

下面依次解決上面的問題:

1、生成全域性唯一的訂單編號

這裡採用了:機器ID+時間戳+自增序列(+userid後兩位); 

這裡的機器id是因為叢集部署的時候,不同機器上的訂單系統的機器id是不一樣的,生成的訂單id也就不一樣了。

時間戳可以精確到毫秒,但是如果每毫秒任然有併發,單純使用時間戳並不能完全生成唯一訂單id

自增序列每個表自己的自增序列,保證單表的訂單id唯一

userid後兩位,給訂單id賦予一定含義。

詳情可見:分散式系統唯一ID生成方案彙總

 

2、查詢複雜度的降低-----mycat資料庫中介軟體

中間價可以使用阿里的mycat連線,具體使用檢視mycat文件。優點:程式碼實現簡單,跟分庫前差不多。

而直接使用jdbc連結,需要自己計算哪條訂單存入哪個庫,優點是:直接連結資料庫效能更好,缺點是程式碼複雜度高。

 

3、買家賣家訂單設計

由於買家與賣家有不同的查詢特性,買家(使用者)只會查詢自己的訂單,而賣家(商家)會查詢自己店鋪的訂單,還有管理者,他可以查詢所有的訂單並且統計。

訂單的查詢特性是:一般三個月之前的訂單是很少被查詢的。

所以我這裡設計了兩個訂單表,一個是針對使用者的,一個是針對商家和管理者的。

使用者訂單表UOrderId根據訂單的後兩位(也就是生成訂單id時的使用者id後兩位),進行分庫分表,這樣分得的訂單表中,同一個使用者的訂單一定是在一個表中的,使用mycat查詢的時候,減少了mycat的計算等的操作。

商家訂單表OOrderId根據訂單產生的時間進行分庫分表,我們按照一個月一個月分表,分為12個表,商家和管理者查詢這個表,由於經常檢視的表只有幾個,所以,只會查詢特定的幾個表,減少查詢的複雜度。

 

4、擴容問題

由於訂單系統不僅會通過訂單號查詢訂單,還有可能會通過使用者id查詢,通過商家id查詢,查詢所有訂單等,但是無論是哪種身份的使用者查詢都有一個特性,就是很少會查詢三個月之前的資料,所以我們可以考慮吧三個月之前的資料遷移到歷史資料庫中,給新的資料騰空間,從而解決容量增長的問題。

例如:我們可以在3,6,9,12月份的月底進行資料遷移,在6月底,將3月之前的資料都遷移到歷史資料庫中,歷史資料庫不要求有多高的效能,只要空間足夠就可以,節約成本。

二、使用MQ,起緩衝作用,緩解併發問題

這裡我們在生成訂單的時候,不直接呼叫生成訂單的介面,而是將訂單資訊傳送到MQ中,利用Mq佇列先進先出的特性,一個是使用MQ系統做緩衝作用,還有就是作為MQ的消費者,一定是一個一個處理訂單,所以,減少了訂單系統的壓力,也減少了併發。

三、訂單系統流程