訂單中心架構設計與實踐

作者:中 v 中

來源:https://www.jianshu.com/p/84da619ce203

一、背景

隨着公司業務增長,如果每天 1000 多萬筆訂單的話,3 個月將有約 10 億的訂單量,之前數據庫採用單庫單表的形式已經不滿足於業務需求,數據庫改造迫在眉睫。

二、訂單數據如何劃分

我們可以將訂單數據劃分成兩大類型:分別是熱數據和冷數據。

可能這裏有個疑惑爲什麼要將冷數據分成兩類,因爲根據實際場景需求,用戶基本不會去查看 1 年前的數據,如果將這部分數據還存儲在 db 中,那麼成本會非常高,而且也不便於維護。另外如果真遇到有個別用戶需要查看 1 年前的訂單信息,可以讓用戶走離線數據查看。

對於這三類數據的存儲,目前規劃如下:

三、MySql 如何分庫分表

3.1、按業務拆分

在業務初始階段,爲了加快應用上線和快速迭代,很多應用都採用集中式的架構。但是隨着業務系統的擴大,系統匾額越來越複雜,越來越難以維護,開發效率變得越來越低,並且對資源的消耗也變得越來越大,通過硬件提高系統性能的成本會變得更高。

通常一般的電商平臺,包含了用戶、商品、訂單等幾大模塊,簡單的做法是在同一個庫中分別建 4 張表,如下圖所示:

但是隨着業務的提升,將所有業務都放在一個庫中已經變得越來越難以維護,因此我們建議,將不同業務放在不同的庫中,如下圖所示:

牛逼啊!接私活必備的 N 個開源項目!趕快收藏

由圖中我們可以看出,我們將不同的業務放到不同的庫中,將原來所有壓力由同一個庫中分散到不同的庫中,提升了系統的吞吐量。

3.2、分庫與分表

我們知道每臺機器無論配置多麼好它都有自身的物理上限,所以當我們應用已經能觸及或遠遠超出單臺機器的某個上限的時候,我們惟有尋找別的機器的幫助或者繼續升級的我們的硬件,但常見的方案還是通過添加更多的機器來共同承擔壓力。

我們還得考慮當我們的業務邏輯不斷增長,我們的機器能不能通過線性增長就能滿足需求?因此,使用數據庫的分庫分表,能夠立竿見影的提升系統的性能,關於爲什麼要使用數據庫的分庫分表的其他原因這裏不再贅述,主要講具體的實現策略。

(1)分表策略

我們以訂單表爲例,在訂單表中,訂單 id 肯定是不可重複的,因此將該字段當做 shard key 是非常適合的, 其他表類似。假設訂單表的字段如下:

1create table order(2 order_id bigint(11) ,3

我們假設預估單個庫需要分配 100 個表滿足我們的業務需求,我們可以簡單的取模計算出訂單在哪個子表中,例如:order_id % 100,

這時候可能會有人問了,如果我根據 order_id 進行分表規則,但是我想根據 user_id 查詢相應的訂單,不是定位不到哪個子表了嗎,的確是這樣,一旦確定 shard key,就只能根據 shard key 定位到子表進而查詢該子表下的數據;如果確實想根據 user_id 去查詢相關訂單,那應該將 shard key 設置爲 user_id, 那分表規則也相應的變更爲:user_id % 100;

(1)分庫實現策略

數據庫分表能夠解決單表數據量很大的時候數據查詢的效率問題,但是無法給數據庫的併發操作帶來效率上的提高,因爲分表的實質還是在一個數據庫上進行的操作,很容易受數據庫 IO 性能的限制。

因此,如何將數據庫 IO 性能的問題平均分配出來,很顯然將數據進行分庫操作可以很好地解決單臺數據庫的性能問題。

分庫策略與分表策略的實現很相似,最簡單的都是可以通過取模的方式進行路由。

我們還是以 order 表舉例,

例如:order_id % 庫容量,

如果 order_id 不是整數類型,可以先 hash 在進行取模,

例如:hash(order_id) % 庫容量

(3)分庫分表結合使用策略

數據庫分表可以解決單表海量數據的查詢性能問題,分庫可以解決單臺數據庫的併發訪問壓力問題。有時候,我們需要同時考慮這兩個問題,因此,我們既需要對單表進行分表操作,還需要進行分庫操作,以便同時擴展系統的併發處理能力和提升單表的查詢性能,就是我們使用到的分庫分表。

如果使用分庫分表結合使用的話,不能簡單進行 order_id 取模操作,需要加一箇中間變量用來打散到不同的子表,公式如下:

中間變量 = shard key %(庫數量 * 單個庫的表數量);2 庫序號 = 取整(中間變量/單

例如:數據庫有 10 個,每一個庫中有 100 個數據表,用戶的 order_id=1001,按照上述的路由策略,可得:

這樣的話,對於 order_id=1001,將被路由到第 1 個數據庫的第 2 個表中 (索引 0 代表 1,依次類推)。另外,搜索公衆號 Linux 就該這樣學後臺回覆 “猴子”,獲取一份驚喜禮包。

三、整體架構設計

從圖中我們將請求分成 read 和 write 請求,write 請求比較簡單,就是根據分庫分表規則寫入 db 即可。

對於 read 請求,我們需要計算出查詢的是熱數據還是冷數據,一般 order_id 生成規則如下,“商戶所在地區號 + 時間戳 + 隨機數”,我們可以根據時間戳計算出查詢的是熱數據還是冷數據,(當然具體業務需要具體對待,這裏不再詳細闡述)

另外架構圖中的冷數據指的是 3 個月~ 12 個月前的數據,如果是查詢一年前的數據,建議直接離線查 hive 即可。

圖中有一個定時 Job,主要用來定時遷移訂單數據,需要將冷數據分別遷移到 ES 和 hive 中。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/K7HFN9622g77OZY7xxM8jA