一、分庫分表背景
老調常談,直接原因是數據量的鍋。傳統IT/業務量較小的企業裏也許很難體現出,而在大型互聯網企業裏,數據量增長巨快,像我們公司埋點數據的指標拍平後,每天有億級別的數據。按阿里巴巴給出的開發規範,單表超過500w行就要考慮分表,因爲此時單機的性能已經到瓶頸。
所以,後來牛人們提出分佈式。一臺機器頂不上,那就多臺,人多自然力量大,化整爲零來解決。
具體到數據的存儲上,那就是按照一定的規則,將數據庫劃分到不同的庫/表中,而後取數的時候去特定的存儲位置上進行獲取。
二、引入分庫分表時機1
我們在編碼過程中,分庫分表可以在以下幾個層次切入:
- 代碼層
完全需要開發人員來編寫分庫分表的邏輯
- 框架層
開發人員擴展框架來實現分庫分表
- 驅動層
由第三方實現驅動層的包,供開發人員調用。如Sharding-JDBC、TDDL等。
- 代理層
由第三方實現,啓動服務僞裝成數據庫,接受業務端的連接。如MyCAT、Sharding-Proxy等。
- 實現層
底層存儲數據的軟件變更,如採用TiDB
三、分庫分表實現
目前來說,無論從驅動層還是代理層的層面切入,第三方的實現流程大體都要經過如下幾步:
- SQL解析
可以使用開源的SQL解析器,如阿里的Druid,或者採用ANTLR創建自己的SQL編譯器
- SQL路由
SQL路由的意思是指根據傳遞的數據,經過特定規則能傳遞到正確的庫/表來操作數據。如訂單庫中,根據用戶id分庫,然後依據訂單id分表,來插入/更新訂單信息。
在這個過程中,主要是規則的制定,特別是需要注意數據分庫/表後的數據平均。常見的規則譬如取模、哈希和直接指定庫/表(尾數爲1落1庫,尾數爲2落2庫,尾數爲3落3庫)等。
- SQL改寫
經過SQL路由後,分庫分表應用模塊已經知道某條SQL語句對應的庫及表,此時需要改寫SQL語句的庫/表讓其執行在正確的庫/表中。如:
SELECT id, order_id, user_id from demo_ds.t_order
可能會改寫爲:
SELECT id, order_id, user_id from demo_ds_0.t_order_0
-
SQL執行
-
結果歸併
對於聚合類的查詢,當從每個庫/表中獲取出聚合的結果,比如MAX
,分庫分表模塊還需要歸納,最終取出各個庫/表中的最大值進行綜合比較返回。