何時分庫分表
MySQL單表(innoDB)可以存儲10億級數據,只是這時候性能比較差,業界公認MySQL單表容量在1KW以下是最佳狀態,因為這時它的BTREE索引樹高在3~5之間。
參考阿里開發手冊建議:
1.單表行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表;如果預計三年后的數據量根本達不到這個級別,請不要在創建表時就分庫分表。
2.實際情況受mysql機器配置等多方面影響,可能數據量很大但性能依舊不錯,但考慮后續發展一定要進行分庫分表考慮。
如何分庫分表
設置合適的分片數量
根據實際的業務場景選擇合適的分片數據,參考如下:
- 滿足當前數據平均后的數據量在一個合理的范圍(<=100w)
- 預估未來5年的數據量發展情況,數據量在一個合理的范圍(500w左右,有合理的歸檔備份機制)
選擇合適的分片字段
根據實際的業務場景選擇適當的分片字段,要達到如下要求:
- 字段類型常規
- 字段不易過多
- 字段應該是業務場景大多數都會被使用的
設計合理的分片規則
分表數量和分表字段確定后,要設計一個合理的分表規則,良好的分表規則要達到如下條件:
- 規則計算高效,邏輯清晰
- 規則計算后,分片數據均勻
- 方便后續擴容分片
如何保證分片數據均勻,參考:
- 分片字段本身就是隨機均勻的,可以直接使用
- 分片字段隨機,但不均勻,如對總分片取模后,會導致數據不均勻,建議先對分片字段進行2次隨機處理(如:zebra提供的:md5/crc32 方法)
如何保證方便后續分片擴容,參考:
- 如果是按照時間或數值范圍進行分片,只需要創建分片庫表,修改分片規則,立即生效
- 如果是hash分片,條件允許可考慮停服遷移,停止服務,將數據按新分片規則進行遷移,修改分片規則,啟動服務
- 某些情況下可考慮升級從庫,如2分庫擴容為4分庫,可將從庫升級為主庫並修改分片規則,后續可將冗余的數據進行清除並補上缺失的從庫。
- 數據庫雙寫,同時按新老分片規則寫入兩套物理表,並逐漸下線老數據模型,可參考-新老遷移參考
SQL使用注意
如何高效的使用分庫分表,核心是做到盡量的路由到最少的表,最好是只路由到一個表里面
核心規則如下:
- 能帶分片字段的就盡量把其帶上
- 盡量不使用范圍查詢
- 無分片使用limit時不要查詢太靠后的數據
- 盡量不要使用復雜的sql
- sql寫法盡量規范
新老遷移方案參考
階段一
- 數據庫雙寫(事務成功以老模型為准),查詢走老模型。
- 每日job數據對賬,並將差異補平。
- 通過job導歷史數據。
階段二
- 歷史數據導入完畢並且數據對賬無誤。
- 依然是數據庫雙寫,但是事務成功與否以新模型為准,在線查詢切新模型。
- 每日job數據對賬,將差異補平。
階段三
- 老模型不再同步寫入,異步補齊(同步數據終態)。
- 此階段只有離線數據依然依賴老的模型,並且下游的依賴非常多,待改造完就可以完全廢除老模型了。