【乾貨】分庫分表最佳實踐

有夢想的老王發表於2021-09-10

何時分庫分表

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資料對賬,將差異補平。

階段三

  • 老模型不再同步寫入,非同步補齊(同步資料終態)。
  • 此階段只有離線資料依然依賴老的模型,並且下游的依賴非常多,待改造完就可以完全廢除老模型了。

相關文章