02.數據庫分庫分表-分表策略

摘要

上一篇文章已經說根據school_id進行分表。通常我們的分表策略有兩種方式

  • 取模分表
  • 範圍分表

取模分表

所謂的取模分表就是對分表key取模,通過預估數據量確定分幾張表那麼則模以幾。在這裏插入圖片描述

在我們設計系統之前,可以先預估一下大概這幾年的數據量,如:8000萬。每張表我們可以容納2000萬,也我們可以設計4張表進行存儲。對指定的路由key(如:school_id)對分表總數進行取模,上圖中,id=13的任務,對4進行取模,也就是會得到1,那此訂單會放到1表中。id=26的訂單,取模得到爲2,就會放到2表中。

優點
任務數據可以均勻的放到那4張表中,這樣此任務進行操作時,就不會有熱點問題。

學習任務有個特點就是時間屬性,一般用戶操作任務數據,都會集中到這段時間的任務。如果這段時間產生的任務都在同一張任務表中,那就會形成熱點,那張表的壓力會比較大。

缺點
將來的數據擴容會很難。

隨着業務的發展時間的推移,學習任務量很大,超出了8000萬的量,那我們就需要增加分表數。如果我們增加4個表。一旦我們增加了分表的總數,取模的基數就會變成8,以前id=13的任務按照此方案就會到5表中查詢,但之前的此任務數據在1表的,這樣就導致了數據查不到。就是因爲取模的基數產生了變化。

在這裏插入圖片描述
遇到這個情況,我們小夥伴想到的方案就是做數據遷移,把之前的8000萬數據,重新做一個hash方案,放到新的規劃分表中。也就是我們要做數據遷移。


範圍分表

範圍分表方案也就是以範圍進行拆分數據。
在這裏插入圖片描述

範圍方案比較簡單,就是把一定範圍內的任務,存放到一個表中;如上圖school_id=13放到0表中,school_id=23456的放到2表中。設計這個方案時就是前期把表的範圍設計好。通過school_id進行路由存放。

優點
此方案有利於將來的擴容,不需要做數據遷移。即時再增加4張表,之前的4張表的範圍不需要改變,school_id=13的還是在0表,school_id=23456的還是在2表,新增的4張表他們的範圍肯定是 大於 40000之後的範圍劃分的。
缺點
有熱點問題,因爲school_id的值會一直遞增變大,那這段時間的任務是不是會一直在某一張表中,如school_id=1 ~ 10000萬之間,這段時間產生的訂單是不是都會集中到此張表中,這個就導致1表過熱,壓力過大,而其他的表沒有什麼壓力。


分組取模分表

取模分表:擴容不方便
範圍分表:有熱點問題
通過取模分表方式可以既方便擴容又一定程度上緩解熱點問題
在這裏插入圖片描述
看下數據存儲流程
在這裏插入圖片描述

先根據範圍確定是在那個分組,如school_id=12345,根據範圍確定在group_0中,再取模確定組內那張表,如school_id=12345,按4取模確定存儲在task_1表中。
這樣我們擴容時只需要添加對應的group,同時組內的數據均勻分佈在不同的表中,一定程度上緩解熱點問題。


應用

在我們的業務場景中,我們通過評估最終選取了取模分組。因爲通過school_id分表即使根據範圍分組依然無法避免擴容問題。因爲school_id保持不變,學校對應的用戶(學生id)每年都會新增,通過增加school_id的範圍依然無法讓老學校的新學生任務數據落到新表中。

確定了分表方式後需要預估分表數,此處需要注意的是由於採用的取模分組數據擴容不方便,所以需要假設期望一年、兩年、三年數據不擴容需要分多少張表。通過對生產環境數據統計,我們預估單個學校活躍用戶量500人,每個人月任務量40個,mysql單表數據容量2000萬。這樣計算出單個學校每年任務數=5004012=240000。單個mysql表可以支撐的學校數如下:

支撐年份 單表支撐學校數
1 83
2 48
3 23

所以我們計算出預估分表數:

活躍學校數 支撐年份 分表數
500 1 6
2 12
3 18
1000 1 12
2 24
3 36
1500 1 18
2 36
3 54
2000 1 24
2 48
3 72
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章