何時分庫分表
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資料對賬,將差異補平。
階段三
- 老模型不再同步寫入,非同步補齊(同步資料終態)。
- 此階段只有離線資料依然依賴老的模型,並且下游的依賴非常多,待改造完就可以完全廢除老模型了。