本文將以「帖子中心」爲例,介紹「1對多」類業務,隨着數據量的逐步增大,數據庫性能顯著下降,數據庫水平切分相關的架構實踐:算法
1、什麼是1對多關係數據庫
所謂的「1對1」,「1對多」,「多對多」,來自數據庫設計中的「實體-關係」ER模型,用來描述實體之間的映射關係。segmentfault
1對1緩存
這是一個1對1的關係。架構
1對多併發
這是一個1對多的關係。app
多對多數據庫設計
這是一個多對多的關係。分佈式
2、帖子中心業務分析性能
帖子中心是一個典型的1對多業務。
一個用戶能夠發佈多個帖子,一個帖子只對應一個發佈者。
任何脫離業務的架構設計都是耍流氓,先來看看帖子中心對應的業務需求。
帖子中心,是一個提供帖子發佈/修改/刪除/查看/搜索的服務。
寫操做:
讀操做:
在數據量較大,併發量較大的時候,一般經過元數據與索引數據分離的架構來知足不一樣類型的需求:
架構中的幾個關鍵點:
其中,tiezi-center和tiezi-search分別知足兩類不一樣的讀需求:
如上圖所示:
對於寫需求:
如上圖所示:
tiezi-search,搜索架構不是本文的重點(外置索引架構設計,請參見《100億數據1萬屬性數據架構設計》),後文將重點描述帖子中心元數據這一塊的水平切分設計。
3、帖子中心元數據設計
經過帖子中心業務分析,很容易瞭解到,其核心元數據爲:
Tiezi(tid, uid, time, title, content, …);
其中:
數據庫設計上,在業務初期,單庫就能知足元數據存儲要求,其典型的架構設計爲:
在相關字段上創建索引,就能知足相關業務需求:
4、帖子中心水平切分-tid切分法
當數據量愈來愈大時,須要對帖子數據的存儲進行線性擴展。
既然是帖子中心,而且帖子記錄查詢量佔了總請求的90%,很容易想到經過tid字段取模來進行水平切分:
這個方法簡單直接,優勢:
缺點:
如上圖,一個uid訪問須要遍歷全部庫。
5、帖子中心水平切分-uid切分法
有沒有一種切分方法,確保同一個用戶發佈的全部帖子都落在同一個庫上,而在查詢一個用戶發佈的全部帖子時,不須要去遍歷全部的庫呢?
答:使用uid來分庫能夠解決這個問題。
新出現的問題:若是使用uid來分庫,確保了一個用戶的帖子數據落在同一個庫上,那經過tid來查詢,就不知道這個帖子落在哪一個庫上了,豈不是還須要遍歷全庫,須要怎麼優化呢?
答:tid的查詢是單行記錄查詢,只要在數據庫(或者緩存)記錄tid到uid的映射關係,就能解決這個問題。
新增一個索引庫:
t_mapping(tid, uid);
使用uid分庫,並增長索引庫記錄tid到uid的映射關係以後,每當有uid上的查詢:
能夠經過uid直接定位到庫。
每當有tid上的查詢:
這個方法的優勢:
缺點:
6、帖子中心水平切分-基因法
有沒有一種方法,既可以經過uid定位到庫,又不須要創建索引表來進行二次查詢呢,這就是本文要敘述的「1對多」業務分庫最佳實踐,基因法。
什麼是分庫基因?
經過uid分庫,假設分爲16個庫,採用uid%16的方式來進行數據庫路由,這裏的uid%16,其本質是uid的最後4個bit決定這行數據落在哪一個庫上,這4個bit,就是分庫基因。
什麼是基因法分庫?
在「1對多」的業務場景,使用「1」分庫,在「多」的數據id生成時,id末端加入分庫基因,就能同時知足「1」和「多」的分庫查詢需求。
如上圖所示,uid=666的用戶發佈了一條帖子(666的二進制表示爲:1010011010):
(怎麼生成60bit分佈式惟一ID,請參見《分佈式ID生成算法》)
這般,保證了同一個用戶發佈的全部帖子的tid,都落在同一個庫上,tid的最後4個bit都相同,因而:
潛在問題一:同一個uid發佈的tid落在同一個庫上,會不會出現數據不均衡?
答:只要uid是均衡的,每一個用戶發佈的平均帖子數是均衡的,每一個庫的數據就是均衡的。
潛在問題二:最開始分16庫,分庫基因是4bit,將來要擴充成32庫,分庫基因變成了5bit,那怎麼辦?
答:須要提早作好容量預估,例如事先規劃好5年內數據增加256庫足夠,就提早預留8bit基因。
7、總結
將以「帖子中心」爲典型的「1對多」類業務,在架構上,採用元數據與索引數據分離的架構設計方法:
對於元數據的存儲,在數據量較大的狀況下,有三種常見的切分方法:
對於1對多的業務場景,分庫架構再也不是瓶頸。
[1] 1對多業務,數據庫水平切分架構一次搞定
http://zhuanlan.51cto.com/art/201707/544573.htm
[2] 啥,又要爲表增長一列屬性?
http://chuansong.me/n/1298388046739
[3] 分庫分表須要考慮的問題及方案
https://segmentfault.com/p/1210000010189004/read#top
[4] 多對多業務,數據庫水平切分架構一次搞定
[5] 多key業務,數據庫水平切分架構一次搞定