数据库分库分表 2026 实战指南
几乎每一个增长中的互联网业务都会撞上同一道墙:单库性能见顶。单库 QPS 五千、十万行表没问题,但当单表数据涨到亿级、单库写入压满磁盘 IOPS、备份从一小时拉到一整天,水平扩展就不再是一个选项而是必须。分库分表是最经典也最复杂的水平扩展手段,做对了支撑亿级用户与万级 QPS,做错了把简单 CRUD 变成跨分片 join 的噩梦。本文系统梳理 2026 年分库分表的关键决策:垂直拆分与水平拆分如何选、Hash 与范围分片各自适用什么场景、ShardingSphere 与 Vitess 等中间件对比、跨分片分布式事务(2PC/Saga/TCC)、平滑迁移路径,以及最重要的——什么时候才真的需要分库分表。
一、什么时候才需要分库分表
分库分表是高成本方案,引入前必须先穷举垂直优化手段。常见的"还没到需要分片"信号包括:单表行数低于 5000 万、QPS 低于 5000、磁盘使用低于 70%、备份恢复时间可接受、慢查询主要由缺索引或写得烂引起。任何一项不满足都先优化它。
真正需要分片的信号:单表 1 亿行以上、写 QPS 超过 1 万、磁盘超过 70% 且业务持续增长、备份耗时超过维护窗口、master 主从复制延迟显著。即便如此,先尝试这些替代方案——读写分离把读流量打到从库、分区表(partition)按时间分区、冷热分离归档历史数据、引入 Redis 缓存把热点读拦在数据库前。这些做完性能仍不达标才是分片时机。本站 Redis vs Memcached 一文讨论了缓存层选型,MySQL vs PostgreSQL 对比了数据库本身的扩展能力。
二、垂直拆分:先做的事
垂直拆分按业务把不同表分到不同库。早期单库 user、order、product、payment 全在一起,访问量上来后按业务拆成 user_db、order_db 等独立库。优点是改造小(每个业务自己读自己的库)、爆炸半径有限(一个库挂只影响一个业务)、便于团队解耦(各业务独立 DBA、独立优化)。这是大多数公司的第一次拆分。
垂直拆分还有另一种维度:垂直分表,把一张大表的字段按访问频率拆开。比如用户表有 user_id、name、email(高频)+ avatar_url、bio、address(中频)+ raw_metadata、preferences_json(低频大字段),可以拆成 user_main + user_extra + user_settings 三张表,主表小、查询快、缓存命中率高。垂直拆分是低成本高收益的优化,应该尽早做,能延缓水平拆分时机数年。
三、水平拆分(分片):核心选型
当垂直拆分到极致单表仍然过大,就要走水平拆分——把同一张表按某个字段分到多个表/库。关键问题是选择 sharding key 与分片策略。Sharding key 选择原则:业务查询主路径都包含它(否则查询要扫所有分片)、值分布均匀(避免热点)、不可变(变了要数据迁移)。最常见的选择:用户中心型业务用 user_id,订单业务用 user_id 或 order_id。
分片策略两大主流:Hash 分片(user_id % N,对 N 取模)数据均匀、避免热点,但范围查询要扫所有分片、扩容时大量数据要重新分配(一致性 Hash 可缓解)。范围分片(按时间或 ID 区间)范围查询快、扩容只需新增分片,但容易热点——最新数据全部落在最新分片,老分片几乎不再写。实际选择:读多写少且无明显时间维度的业务用 Hash,时序型业务(订单、日志)用范围 + Hash 二级(按月分片再按用户 Hash)。可以用本站的 哈希与加密区别了解一致性 Hash 原理。
四、ShardingSphere 与 Vitess 中间件对比
分片中间件的作用是对应用屏蔽分片细节:应用照常写 SQL,中间件解析后路由到正确分片、聚合结果。两大主流方案是 ShardingSphere 与 Vitess。
ShardingSphere(Apache 顶级项目)有两种部署模式:JDBC 模式作为驱动嵌入应用,零网络开销、性能最好;Proxy 模式作为独立代理,对应用透明、支持多语言。Java 生态首选,国内大厂如美团、京东、当当深度使用,社区活跃。Vitess 源自 YouTube 用 MySQL 撑全球流量的方案,已捐给 CNCF,Kubernetes 原生、自带 VTGate 路由、VTOrc 自动故障转移、VReplication 在线迁移,云原生与多语言团队优选。Slack、PlanetScale、HubSpot 都基于 Vitess。两者性能上都已经过亿级 QPS 验证,选型主要看技术栈与运维偏好。还有一些云厂商方案如 PolarDB-X、TDSQL,开箱即用但有锁定。
五、跨分片 join 与全局二级索引
分片后最大的痛点是跨分片操作。最常见的是 join:两张表如果按相同 sharding key 分片可以并置(co-location)join,否则中间件会做"广播 join"——把小表广播到所有分片再 join,性能大幅下降。最佳实践是设计阶段就规划好哪些表要 join,按相同 key 分片。
第二大痛点是非 sharding key 查询。比如订单按 user_id 分片,但运营要按 order_id 查订单详情,这就要扫所有分片。解法是建立全局二级索引——把 order_id 到 user_id 的映射单独存一张全局表(或 Redis),查询先查映射定位 user_id,再走主路径。常见的还有反向索引、ES 异构索引等思路。需要权衡一致性(异步同步会有延迟)与性能。聚合查询(count、sum、group by)也要中间件分发到各分片再合并,对带 sharding key 的查询性能好,跨分片聚合要谨慎使用。
六、分布式事务:2PC、Saga、TCC
分片后跨分片事务无法用本地事务保证。三种主流方案:2PC(两阶段提交)由协调者发 prepare、各分片落库但不提交,全部 ack 后协调者发 commit;保证强一致但性能差(两次往返、锁阻塞)、协调者单点风险高,适合金融核心系统。MySQL 的 XA 事务就是 2PC。
Saga 把长事务拆成多个本地事务,每个本地事务对应一个补偿操作。如果中间步骤失败,依次执行已完成步骤的补偿事务回滚。最终一致而非强一致。适合订单、报销这种长流程业务。开源框架:Seata 的 Saga 模式、阿里 TCC-Transaction。TCC(Try-Confirm-Cancel)是改进的 Saga:每个服务实现 try(资源预留)、confirm(提交)、cancel(回滚)三个接口,业务侵入性高但灵活,金融账务常用。最简单的折中是本地消息表(最大努力通知):业务和消息插同一个本地事务,定时任务扫描未发送的消息投递到消息队列,下游幂等消费。可以参考 微服务架构一文了解相关取舍。
七、平滑迁移:双写与灰度
分库分表最容易翻车的环节是迁移。生产环境数据量已经数 TB,停机迁移不可接受。经典方案是双写灰度迁移,分五步:第一步上线双写代码,写老库为主、新库为辅,新库写失败不影响主流程,目的是让新增数据进入新库。第二步用 DataX、Canal 等工具把老库历史数据全量 + 增量同步到新库。第三步开数据对账,定期比对新老库一致性,发现不一致告警。第四步灰度切读:先 1% 读流量切到新库,观察一周再扩到 10%、50%、100%,每一步都可一键回退。第五步切写:把主写从老库切到新库,老库降为备份;观察一段时间后下线老库。
关键工具:Canal(阿里)订阅 MySQL binlog 增量同步;DataX 离线全量同步;Yugong(蚂蚁)专为分库分表迁移设计;自研对账工具。整个过程通常持续一到三个月,必须有完整的回滚预案、监控告警、应急 SOP。最大的隐患是双写期间业务变更——新增字段、新功能上线,必须保证老库与新库 schema 同步。
八、引入时机与替代方案
分库分表是最后手段。在做出引入决定前,认真评估这些替代方案:(1)NewSQL 数据库——TiDB、OceanBase、CockroachDB 提供原生分布式能力,无需应用层分片,运维成本低很多,亿级数据是其甜点。(2)NoSQL——MongoDB sharding、Cassandra、HBase 等天生分布式,适合非关系型场景。(3)专业搜索引擎——Elasticsearch 处理大数据量复杂查询。(4)OLAP 数据库——ClickHouse、Doris 处理分析型查询,让 OLTP 库解脱。(5)数据归档——把超过 6 个月的订单归档到对象存储,OLTP 库只留热数据。
2026 年的趋势是 NewSQL 取代传统分库分表的趋势愈发明显。对中小公司,先尝试 TiDB 等方案以避免引入分库分表的复杂度,是更明智的选择。但对超大规模、强 MySQL 生态依赖、定制化需求高的场景,分库分表 + ShardingSphere 仍是不可替代的方案。决策时考虑团队 DBA 能力、业务复杂度、未来三年增长预期,而不是盲目跟风。可以用本站的 JSON 格式化工具调试分片中间件的路由日志。
常见问题
什么时候才需要分库分表?
单表超过 5000 万行、单库写 QPS 超过 5000、磁盘使用超过 70% 时考虑。优先尝试垂直优化:加索引、读写分离、归档历史数据、升级硬件、引入缓存。这些都做完仍打满才上分片。过早分片会带来巨大复杂度(跨分片 join、分布式事务、迁移),得不偿失。NewSQL 也是值得考虑的替代方案。
Hash 分片和范围分片怎么选?
Hash 分片(如 user_id 取模 16)数据均匀,避免热点,但范围查询性能差、扩容时需要重新分配。范围分片(如按月份分表)范围查询快、扩容简单(新增分片不影响旧数据),但容易热点(最新分片承担全部写入)。读多业务用 Hash,时序业务用范围,两者也可组合(先按时间再 Hash)。一致性 Hash 可缓解 Hash 分片的扩容问题。
ShardingSphere 和 Vitess 如何选?
ShardingSphere 是 Java 生态主流,作为 JDBC 驱动或独立代理 Proxy 部署,对应用透明,国内大厂广泛采用。Vitess 源自 YouTube 的 MySQL 分片方案,云原生、Kubernetes 友好,国外大厂使用更多。Java 项目首选 ShardingSphere,云原生与多语言团队选 Vitess。两者都已经历过亿级 QPS 验证,最终选择主要看技术栈与运维偏好。
2PC、Saga、TCC 三种分布式事务怎么选?
2PC(两阶段提交)强一致但性能差、阻塞高,金融核心系统用。Saga 通过补偿事务实现最终一致,长流程业务(订单、报销)用,对失败补偿可接受。TCC(Try-Confirm-Cancel)是改进的 Saga,业务侵入性高但灵活,金融场景用。多数互联网业务用 Saga 或者本地消息表已经够用。Seata 框架同时支持 AT、TCC、Saga 多种模式。
分库分表后怎么平滑迁移?
经典方案是双写迁移:新老库同时写老库为主;全量同步老库历史数据到新库;切读到新库灰度验证;切写到新库为主,老库降级;观察一段时间后下线老库。整个过程需要可逆开关、数据对账工具、回滚预案。常用工具有 Canal 增量同步、DataX 全量同步。整个迁移通常持续一到三个月,必须有完整的应急 SOP。
相关工具
- JSON 格式化工具 — 调试分片中间件路由日志
- MySQL vs PostgreSQL — 数据库本身扩展能力对比
- 微服务 vs 单体架构 — 分布式系统取舍