1. 程式人生 > >海量數據存儲--分庫分表策略詳解 (轉)

海量數據存儲--分庫分表策略詳解 (轉)

單例 海量 隨著 很難 分配 第一次 IT 策略 att

一、背景:
系統剛開始的時候,數據庫都是單庫單表結構。隨著業務量的增加進行第一次數據庫升級,根據業務垂直拆分數據庫,這樣多變成多個業務數據庫,每個數據庫裏面還是單表結構。接下來,繼續隨著業務量的繼續增加,單表已經很難承受數據量,就要進行分表,這個時候就是,多個業務庫,每個業務庫下對需要分表的表進行分表。再接下來,隨著應用的增加,數據庫IO,磁盤等等都抗不住了,就要把分表的表分到多個庫,這樣就形成了如下的結構。

技術分享圖片

重點:本文主要討論的是分庫分表的策略,也就是分庫分表的規則或者說是算法。

二、分庫分表的依據--分庫分表字段的選擇
分庫分表首先要確定根據哪個字段、或者哪幾個字段進行路由,一般的原則是按使用頻率最高維度的字段去分庫分表,盡量保證高使用維度下只查詢單表


常用的字段有主鍵ID,用戶ID,時間,商戶ID,產品ID,業務類型等等

三、分庫分表策略
主要原理:分區、取模、數據路由表

1. 按照時間區間
1)基本原理:
一定區間內時間產生的數據放到一張表裏面,多個時間區間的表放到一個庫裏面

2)簡單例子:
單庫多表結構,按月分表可以這樣,user_201601,user_201602,...,user_201612這種結構。按年分表可以這樣,user_2016,user_2017,...這種。

3)多庫多表算法:
比如按天分表,每天一張表,當單庫超過100張表的時候,進行分庫到下一張表。那麽假如第一張報表在庫BD0,表名是user_20160201。從DB0.user_20160201,..到DB0.user_20160511就100張表了,接下來就要進行分庫了,進入20160512,就是DB1.user_20160512,這個算法就是上線的時候定一個上線日期,具體算法如下

庫ID = (當前日期 - 上線日期)/ 100
表ID = user_yyyyMMdd
註:好處是可以直接根據時間經過簡單計算定位到哪個庫和哪個表


還有一種算法:
庫ID = (當前日期 - 上線日期)/ 100
表ID = (當前日期 - 上線日期) % 100
表名如下: DB0.user_0001, user_0002,....,user_01000。
註:表名和庫名都要經過計算,比較麻煩


4)按月分表,每個月一張表;這種情況,一般就不用分庫了,一年12張表說明量也不會特別大,如果量特別大,或者是熱點數據,可以一年分一個庫,具體算法和上面差不多。

5)按季度分表,基本不用分庫。
6)按年分表,肯定不用分庫了,沒有必要了。

2. 按照主鍵ID區間
對於自增的主鍵ID,可以按照ID區間進行分表,以1000萬數據量為分界線,對線性的ID進行切割分表,每漲到1000萬數據,分到下一張表,超過一定數目的表,進行分庫。

庫ID = 主鍵ID / 1000萬 / 100
表ID = 主鍵ID / 1000萬 % 100
如:DB0.user_0000,...,DB0.user_0099, DB1.user_0000,...,DB1.user_0099


3. 按照指定字段hash後再取模
如果要取模的字段不是整數型,要先hash後,再通過取模算法,算出在哪個庫和那個表。具體算法,參照下面的按用戶ID取模。

4. 按照用戶ID取模
這裏把按照用戶ID取模單獨拎出來,因為就使用而言,是使用場景最多的情況,很多時候都是用戶相關數據量最大,需要分庫分表,查詢維度更多也是按照用戶來查詢,所以對用戶取模,讓同一個用戶的數據落到一張表裏面,再好不過了。

案例:假設用戶ID是整數型的。庫數量要分4庫,每個庫表數量8表,一共32張表。

原理講解:
一共要分4庫,8表,共32張表,也就是1到32的用戶ID要平均分配到每張表應該有一條數據,這樣就有兩種分法。
1) 1到8是第一個庫,9到16第二個庫,17到24第三個庫,25到32是第四個庫,每個庫裏面表的編號都是0到3,這個原則是一個庫裏面一個一個分,分完再下一個庫一個一個分,保證不重復,不漏掉。
2)1,5,9這樣每隔4個一個庫,2開頭隔4個一個庫,這個原則是一個庫分一個,在分下一個庫,一圈走完,再在第一庫沒分到的表繼續分,也保證了不重復,不漏掉原則。

庫ID = userId % 庫數量4
表ID = userId / 庫數量4 % 表數量8

或者

庫ID = userId / 表數量4 % 庫數量4
表ID = userId % 表數量8


算法圖示如下:
技術分享圖片


5. 數據路由表
如果分庫分表的算法很復雜,可以通過路由表+程序算法,來存儲和計算分庫分表規則,不過一般不建議,分庫分表搞得太復雜,不便於維護和查詢問題

四、各個方案對比
分區算法
優點:線性擴容,平滑擴容,不需要數據遷移
缺點:存在熱點數據,非時間維度查詢多的情況,聚合復雜
建議:冷數據,用戶維度查詢少,且數據量大的情況用分區算法

取模算法
優點:同一個熱點的數據可以做到一個表裏面,查詢方便
缺點:擴容不是很方便,需要數據遷移
建議:用戶維度查詢多,熱點維度查詢多的情況,建議使用

註:
分庫分表的核心是未來數據量的預估,根據預估和實際使用情況來確定分庫分表方案,一般像訂單類數據以用戶維度取模分表最好,商品數據以商戶取模最好,簽到等活動流水數據時間分區最好。
取模方案擴容的解決:一、可以提前按照預估方案創建庫和表,前期放到一個DB,後期遷移,或者一次性弄好 二、可以按照預估的方案去確定分庫和分表的後綴ID,但是前期只創建一部分庫和表。例如:最終4庫,每個庫16個表。後綴應該是0000----0315共64個表的後綴,前期可以一個庫,4個表,也就是所有數據都在這個四張表裏面。
0000--0003-----》0000表
0100--0103-----》0000表
0200--0203-----》0000表
0300--0303-----》0000表

0004--0007-----》0004表
0104--0107-----》0004表
0204--0207-----》0004表
0304--0307-----》0004表

0008--0011-----》0008表
0108--0111-----》0008表
0208--0211-----》0008表
0308--0311-----》0008表

0012--0015-----》0012表
0112--0115-----》0012表
0212--0215-----》0012表
0312--0315-----》0012表

後續可以二分法,遷移數據,擴容。

原文地址:http://825635381.iteye.com/blog/2368838

海量數據存儲--分庫分表策略詳解 (轉)