10億級別訂單的分庫分表方案
背景
隨著公司業務增長,如果每天1000多萬筆訂單的話,3個月將有約10億的訂單量,之前資料庫採用單庫單表的形式已經不滿足於業務需求,資料庫改造迫在眉睫。
訂單資料如何劃分?
我們可以將訂單資料劃分成兩大型別:分別是熱資料和冷資料。
熱資料:3個月內的訂單資料,查詢實時性較高。
冷資料A:3個月 ~ 12個月前的訂單資料,查詢頻率不高。
冷資料B:1年前的訂單資料,幾乎不會查詢,只有偶爾的查詢需求。
可能這裡有個疑惑為什麼要將冷資料分成兩類,因為根據實際場景需求,使用者基本不會去檢視1年前的資料,如果將這部分資料還儲存在db中,那麼成本會非常高,而且也不便於維護。另外如果真遇到有個別使用者需要檢視1年前的訂單資訊,可以讓使用者走離線資料檢視。
對於這三類資料的儲存,目前規劃如下:
熱資料: 使用mysql進行儲存,當然需要分庫分表
冷資料A: 對於這類資料可以儲存在ES中,利用搜尋引擎的特性基本上也可以做到比較快的查詢。
冷資料B: 對於這類不經常查詢的資料,可以存放到hive中
MySql 如何分庫分表
一、按業務拆分
在業務初始階段,為了加快應用上線和快速迭代,很多應用都採用集中式的架構。但是隨著業務系統的擴大,系統匾額越來越複雜,越來越難以維護,開發效率變得越來越低,並且對資源的消耗也變得越來越大,通過硬體提高系統效能的成本會變得更高。
通常一般的電商平臺,包含了使用者、商品、訂單等幾大模組,簡單的做法是在同一個庫中分別建4張表,如下圖所示:
但是隨著業務的提升,將所有業務都放在一個庫中已經變得越來越難以維護,因此我們建議,將不同業務放在不同的庫中,如下圖所示:
由圖中我們可以看出,我們將不同的業務放到不同的庫中,將原來所有壓力由同一個庫中分散到不同的庫中,提升了系統的吞吐量。
二、分庫與分表
我們知道每臺機器無論配置多麼好它都有自身的物理上限,所以當我們應用已經能觸及或遠遠超出單臺機器的某個上限的時候,我們惟有尋找別的機器的幫助或者繼續升級的我們的硬體,但常見的方案還是通過新增更多的機器來共同承擔壓力。
我們還得考慮當我們的業務邏輯不斷增長,我們的機器能不能通過線性增長就能滿足需求?因此,使用資料庫的分庫分表,能夠立竿見影的提升系統的效能,關於為什麼要使用資料庫的分庫分表的其他原因這裡不再贅述,主要講具體的實現策略。
1)、分表策略
我們以訂單表為例,在訂單表中,訂單id肯定是不可重複的,因此將該欄位當做shard key 是非常適合的,其他表類似。假設訂單表的欄位如下:
1createtableorder(
2order_idbigint(11) ,
3user_idbigint(11),
4phonevarchar(15),
5...
6)
我們假設預估單個庫需要分配100個表滿足我們的業務需求,我們可以簡單的取模計算出訂單在哪個子表中,例如: order_id % 100,
這時候可能會有人問了,如果我根據order_id 進行分表規則,但是我想根據user_id 查詢相應的訂單,不是定位不到哪個子表了嗎,的確是這樣,一旦確定shard key,就只能根據shard key定位到子表進而查詢該子表下的資料;如果確實想根據user_id 去查詢相關訂單,那應該將shard key設定為user_id, 那分表規則也相應的變更為: user_id % 100;
2)、分庫實現策略
資料庫分表能夠解決單表資料量很大的時候資料查詢的效率問題,但是無法給資料庫的併發操作帶來效率上的提高,因為分表的實質還是在一個資料庫上進行的操作,很容易受資料庫IO效能的限制。
因此,如何將資料庫IO效能的問題平均分配出來,很顯然將資料進行分庫操作可以很好地解決單臺資料庫的效能問題。
分庫策略與分表策略的實現很相似,最簡單的都是可以通過取模的方式進行路由。
我們還是以order表舉例,
例如:order_id % 庫容量,
如果order_id 不是整數型別,可以先hash 在進行取模,
例如: hash(order_id) % 庫容量
3)、分庫分表結合使用策略
資料庫分表可以解決單表海量資料的查詢效能問題,分庫可以解決單臺資料庫的併發訪問壓力問題。有時候,我們需要同時考慮這兩個問題,因此,我們既需要對單表進行分表操作,還需要進行分庫操作,以便同時擴充套件系統的併發處理能力和提升單表的查詢效能,就是我們使用到的分庫分表。
如果使用分庫分表結合使用的話,不能簡單進行order_id 取模操作,需要加一箇中間變數用來打散到不同的子表,公式如下:
1中間變數 = shard key %(庫數量*單個庫的表數量);
2庫序號 = 取整(中間變數/單個庫的表數量);
3表序號 = 中間變數%單個庫的表數量;
例如:資料庫有10個,每一個庫中有100個資料表,使用者的order_id=1001,按照上述的路由策略,可得:
1中間變數 = 1001 %(10*100)= 1;
2庫序號 = 取整(1/100)= 0;
3表序號 = 1%100=1;
這樣的話,對於order_id=1001,將被路由到第1個資料庫的第2個表中(索引0 代表1,依次類推)。
整體架構設計
從圖中我們將請求分成read和write請求,write請求比較簡單,就是根據分庫分表規則寫入db即可。
對於read請求,我們需要計算出查詢的是熱資料還是冷資料,一般order_id生成規則如下,“商戶所在地區號+時間戳+隨機數”,我們可以根據時間戳計算出查詢的是熱資料還是冷資料,(當然具體業務需要具體對待,這裡不再詳細闡述)
另外架構圖中的冷資料指的是3個月~12個月前的資料,如果是查詢一年前的資料,建議直接離線查hive即可。
圖中有一個定時Job,主要用來定時遷移訂單資料,需要將冷資料分別遷移到ES和hive中。
相關文章
- 一種簡單易懂的 MyBatis 分庫分表方案MyBatis
- 常用分庫分表方案
- 分庫分表系列:分庫分表的前世今生
- 分庫分表架構方案設計架構
- MySQL 分庫分表方案,總結太全了。。MySql
- MySQL 常用分庫分表方案,都在這裡了!MySql
- 億萬級分庫分表後如何進行跨表分頁查詢
- 分庫分表
- MySQL資料庫之分庫分表方案MySql資料庫
- 使用TiDB把自己寫分庫分表方案推翻了TiDB
- 分庫分表注意
- [Mysql]分庫分表MySql
- 百億級資料 分庫分表 後怎麼分頁查詢?
- MySQL 資料庫之網際網路常用分庫分表方案MySql資料庫
- 徹底搞清MySQL分庫分表(垂直分庫,垂直分表,水平分庫,水平分表)MySql
- 分庫分表後的分頁查詢
- 資料庫分庫分表的總結資料庫
- MySQL分庫分表的原則MySql
- 記錄分庫分表的文章
- 基因法分庫分表
- Mycat分庫分表(一)
- mycat配置分庫分表
- Mycat分庫分表配置
- 分庫分表總結
- 你分庫分表的姿勢對麼?——詳談水平分庫分表
- [資料庫][分庫分表]分庫分表之後,id主鍵如何處理資料庫
- MySQL:網際網路公司常用分庫分表方案彙總!MySql
- 徹底搞清分庫分表(垂直分庫,垂直分表,水平分庫,水平分表)
- oracle分表效率,資料庫分庫分表是什麼,什麼情況下需要用分庫分表Oracle資料庫
- 分庫分表的基本原理
- 1.4 基於OGG單表到分庫分表資料同步場景
- MyCat分庫分表、讀寫分離
- 資料庫怎麼分庫分表資料庫
- 讀寫分離 & 分庫分表 & 深度分頁
- shrding_jdbc分表分庫JDBC
- 輕鬆理解分庫分表
- 分庫分表插入資料
- 分庫分表的 9種分散式主鍵ID 生成方案,挺全乎的分散式