關於資料庫分庫分表的一點想法

語言: CN / TW / HK

作者:京東物流 何小坡

1 開篇

面對資料的激增,相信大家也都有分庫分表的一些方案,這次的這個分享,算是自己的一個想法,可以當做一個參考方案,也歡迎相互討論。
話不多說,直接進入主題。
日常開發中,實現資料庫的分庫分表,在經常使用工具方面,常用的有像 sharding-sphere、TDDL、Mycat等,然後,根據主鍵key做資料分佈,有兩種常用的方案,Hash取模方案和Range範圍兩種方案,兩種路由演算法,通過指定的key值進行運算後進行資料路由。兩種方案也各有各的優缺點,下面做個梳理。

2 Hash取模

這個方案比較好理解,例如,我們假設未來幾年內,資料能夠增長到3000萬,那,我們可以設計3張表,設表名分別為:table_0, table_1, table_2, 每張表存1000萬資料,我們利用id作為路由key,進行演算法處理,將hash運算後的結果與3進行取模,然後根據所得的值,可以將資料存放到對應的表中。這種方式的優點是,資料可以均勻分散的儲存到對應的表中,不會造成資料全部儲存到一個表中的情況,造成熱點庫表;但是缺點的話也很明顯,就是如果以後再需要擴容的話,再新增表後,例如又新增了 table_3, table_4, table_5, 新的取模就從3變成了6,那這時候,之前的表中的資料,就需要做全量的資料遷移,因為取模的值發生了變化,按照新值取模,可能就找不到資料了。那面對大量的已有資料,資料遷移就比較麻煩了。

3 Range範圍方法

這個方案,也比較好理解,還假設業務後期資料能增長到3000萬,也是可以設計3張表,設為:table_0, table_1, table_2,我看可以按照範圍,將id在0—1000萬的資料,存放在table_0中,id在1000萬—2000萬,存放在table_1中,id在2000萬—3000萬,存放在table_2中。這種方案的話,優點很明顯,就是即使以後擴容,也很方便,直接增加新的表即可;但是缺點的話,也很明顯,資料不能做分散儲存,在某一段兒時間內,資料都會集中儲存在特定的表中,造成單個表壓力過大。

基於以上兩種方式的優勢和劣勢,可以設計一種能夠兼顧兩者優勢的方案,即能使資料能夠分散儲存,也能方便以後的擴容。以下算是一個方案。主要就是利用hash演算法來實現資料的分散儲存,利用range方式能夠比較好的擴容,將兩種方案的優勢結合使用。

4 具體方案

我們假設有一個分組的概念,假設專案初期,預期幾年內的資料,資料可以達到6000萬,可以做如下設計:

如果後面涉及到擴容,那隻需要再直接增加一個分組即可,在分組內,實現資料的分散儲存,擴容也比較方便。

即每次擴容,只需要整體增加一個分組即可,一個分組下,可以儲存將近幾年的資料,所以也不用經常擴容。然後,也可以根據業務情況,將舊資料做歸檔處理,像現在優惠券系統的資料,舊資料就可以做整體歸檔處理,不影響正常業務情況,也減輕生產庫的壓力。

5 總結

分庫分表作為大型應用專案的架構實現方案,確實有一定的複雜性,可以根據當前專案的實際情況,使用適合的工具,做具體開發,最主要的還是需要結合自己的專案的實際業務情況來定,根據資料的分佈以及資料的增長速度,來做結合專案場景的設計。也歡迎大夥一起討論,如果有別的更精妙的“祕籍”,也希望不吝賜教,謝謝。