分库分表演进路线
为什么需要分步演进
分库分表不是一蹴而就的架构变更。从单机到分片集群,是一步步发现问题、解决问题的过程。贸然大改容易失败,逐步演进才能控制风险。
典型的演进路线图
阶段一:单库单表
↓ (读写分离+缓存+索引优化)
阶段二:垂直拆分
↓ (读写分离,分字段,分业务)
阶段三:水平拆分
↓ (分表,分库+分表)
阶段四:分布式架构
↓ (中间件,分布式事务,ES)
阶段一:单机优化
目标
尽量挖掘单机数据库的潜力,推迟拆分。
措施
- SQL 优化:消除慢查询,加合适的索引,避免文件排序和临时表
- 读写分离:主库处理写入,多个从库处理读取
- 缓存:热数据用 Redis 缓存,减少数据库压力
- 冷热分离:历史数据归档到备份表或独立库
什么时候进入下一阶段
- 单机 CPU、内存、磁盘已经升级到顶
- 写入量已经超过单机的最大吞吐能力
- 连接数已经无法再增长
阶段二:垂直拆分
目标
按照业务边界将不同业务的数据分离。
第一步:垂直分表
将大字段(text、blob)从主表中拆分到扩展表。
第二步:垂直分库
按业务模块拆分为独立数据库:
单库 → 用户库、订单库、商品库、支付库
效果
- 不同业务的资源互相隔离
- 可以针对每个业务独立优化和扩容
- 配合微服务架构,每个服务拥有自己的数据库
什么时候进入下一阶段
- 单张表(如订单表)行数超过 1000 万
- 单个垂直库仍然无法承受业务增长
- 归档/清理数据的操作时间过长
阶段三:水平拆分
目标
将大表的数据行分散到多个结构相同的表和数据库中。
第一步:水平分表(仅在同一个库中分表)
orders_0 ~ orders_15: 分布在同一个实例
- 分片键:user_id
- 分片数:16(后续可平滑扩容)
第二步:水平分库 + 分表(跨实例)
ds0.orders_0 ~ ds0.orders_7
ds1.orders_8 ~ ds1.orders_15
ds2.orders_16 ~ ds2.orders_23
ds3.orders_24 ~ ds3.orders_31
关键决策点
| 决策 | 选项 | 说明 |
|---|---|---|
| 分片键 | user_id 或 order_id | 覆盖大多数查询 |
| 分片算法 | 哈希/范围/混合 | 根据访问模式 |
| 分片数量 | 64/128/256 | 按 2 的幂次预留 |
| 中间件 | ShardingSphere/MyCat | 降低代码侵入 |
什么时候进入下一阶段
- 业务查询模式复杂,分片键无法覆盖
- 需要复杂的 JOIN、聚合、排序分析
- 团队需要更强大的查询能力
阶段四:分布式与异构
目标
解决水平拆分后查询能力受限的问题。
措施
- 引入 Elasticsearch:将需要复杂搜索的数据同步到 ES
- 引入搜索引擎:支持全文搜索和复杂聚合
- 数据湖/数仓:离线分析场景
- 分布式 KV:极致性能要求的热数据缓存
演进的关键原则
原则一:不要做”大爆炸”
- 不要在单次上线中同时完成读-写分离 + 分库 + 分表 + 中间件切换
- 每一步独立上线,独立回滚
原则二:保持向下兼容
- 拆分过程中,应用层看到的是同一个接口
- 中间件层或 DAO 层屏蔽分片细节
原则三:预留扩展空间
- 分表数量预留未来 2~3 年的增长
- 分片算法考虑未来的扩容场景
原则四:控制复杂度
- 能不分表就不分,能只用读写分离就不用分库
- 每个”技术决策”都需要匹配”业务价值”
另一个常见误区
很多团队直接从阶段一跳到阶段四,结果:
– 还没弄明白分库分表怎么玩就引入了 ES
– 性能只提升了 10%,复杂度翻了 10 倍
– 出了问题不知道是分片的问题还是 ES 的问题
总结
分库分表的演进路线应该是:单机优化 → 垂直拆分 → 水平拆分 → 分布式异构。每一阶段都解决上一阶段的瓶颈,同时为下一阶段做好准备。核心思想是”够用就好,按需演进”,不要为了技术而技术。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容