前言
分庫分表是應對單庫寫入瓶頸、存儲上限、連接數上限的終極手段。但引入分片鍵、路由層、分布式事務、跨分片查詢等復雜性。本文梳理演進路徑、分片策略、路由模式、衍生難題(聯合查詢、跨庫事務、全局唯一 ID)、中間件選型與最佳實踐。
一、演進三部曲
| 階段 | 架構 | 觸發條件 | 痛點 |
| 1. 單庫單表 | 1 DB, 1 Table | 初創期 | 鎖表 DDL、全表掃描、連接數上限 |
| 2. 單庫多表 | 1 DB, N Tables (水平分表) | 單表 > 1000-2000 萬行 | 跨表 JOIN、事務、存儲上限 |
| 3. 多庫多表 | M DBs, N Tables (分庫+分表) | 單庫 QPS/TPS/存儲/連接數瓶頸 | 路由、分布式事務、全局查詢、運維複雜度 |
二、分片策略:分片鍵選擇與算法
2.1 分片鍵選擇原則
- 業務隔離性:同一分片鍵下的數據盡量在同一分片(如 user_id、shop_id)
- 查詢覆蓋率:高頻查詢條件包含分片鍵,避免廣播查詢
- 數據均勻度:Hash/範圍分布均勻,無熱點分片
- 擴容平滑度:一致性 Hash、範圍預分裂支持無縫擴容
2.2 常用算法
| 算法 | 示例 | 優點 | 缺點 |
| 取模 Hash | user_id % 1024 | 簡單、均勻 | 擴容需重映射(Consistent Hash 緩解) |
| 範圍分片 | user_id 1-1000w -> db1 | 範圍查詢高效、擴容易 | 易產生熱點(新用戶集中新分片) |
| 時間分片 | YYYYMM -> 表 | 歷史數據冷熱分離、歸檔簡單 | 跨時間查詢需聯合 |
| 一致性 Hash | Ketama 算法 | 擴容僅影響少量數據遷移 | 實現複雜、需中間件支持 |
三、路由層實現模式
| 模式 | 代表 | 優點 | 缺點 |
| Client-side SDK | ShardingSphere-JDBC, TDDL | 無代理單點、延遲低、部署簡單 | 多語言需多端實現、升級需發版 |
| Proxy-side | MyCat, ShardingSphere-Proxy, ProxySQL, Vitess | 語言無關、統一治理、對應用透明 | 代理層高可用、增加網絡跳數 |
| Sidecar | Service Mesh 集成 | 基礎設施下沉、零侵入 | 生態成熟度待觀察 |
四、分庫分表衍生的四大難題與對策
4.1 跨分片聯合查詢
- 方案 A:冗余字段(訂單表存 user_name、shop_name),空間換查詢
- 方案 B:應用層組裝(查分片 1、查分片 2、內存 JOIN),適合小結果集
- 方案 C:異構索引(ES、ClickHouse 同步全量/增量),複雜報表、多維分析
- 方案 D:全局表/廣播表(字典表、配置表全量同步到所有分片)
4.2 跨庫分布式事務
- 避免原則:業務設計階段將強一致操作聚合到同一分片
- 柔性事務:TCC(Try-Confirm-Cancel)、SAGA、本地消息表、事務消息(RocketMQ)、Seata AT 模式
- XA 兩階段提交:強一致、性能差、鎖持久長、不推薦高併發核心鏈路
4.3 全局唯一 ID
| 方案 | 示例 | 特點 |
| 雪花算法 | 64bit: 41bit時間+10bit機器+12bit序列 | 趨勢遞增、單機 409w/s、需解決時鐘回撥 |
| 美團 Leaf | 號段模式+雪花雙模式 | 高可用、可監控、號段預取減少 DB 依賴 |
| 百度 UID Generator | RingBuffer 緩存+時間位壓縮 | 高性能、支持 Docker 容器化部署 |
| 數據庫自增+步長 | auto_increment_increment/offset | 簡單、單點寫入瓶頸、不趨勢遞增 |
4.4 讀寫分離 + 分庫分表 疊加架構
┌─────────────┐
│ 應用/路由層 │
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Shard1│ │ Shard2│ │ Shard3│
│ M/S │ │ M/S │ │ M/S │
└───────┘ └───────┘ └───────┘
- 每個分片獨立搭建主從/集群
- 讀請求路由到分片內的 Slave
- 寫請求路由到分片的 Master
- 監控指標:分片級 QPS、延遲、主從延遲、磁盤水位
五、容量規劃經驗值
- 單表 500-800 萬行(純數值型) / 300-500 萬行(含字符串)性能最佳
- 分片數規劃:
分片數 = 預估峰值數據量 / 單表閾值,預留 2-3 倍擴容空間
- 常見規劃:
1024 表 × 16 庫 = 16384 分片,支撐億級用戶、萬億級訂單
六、中間件選型建議(2024 視角)
- ShardingSphere:Apache 頂級項目、JDBC/Proxy 雙模式、生態活躍、支持分布式事務、影子表壓測
- Vitess:YouTube/Slack 驗證、K8s 原生、連接池、查詢重寫、物質化視圖、適合超大規模
- ProxySQL:輕量、高性能、查詢規則、熔斷、Mirror、適合讀寫分離+簡單分片
- 上一篇文章: MySQL 數據拆分三大流派實戰對比:mysqldump、xtrabackup、Transportable Tablespace
- 下一篇文章: MySQL OOM 系列(一):Linux 內存過度提交機制與 OverCommit 深度解析
Copyright ©
程式碼之家 All Rights Reserved