← 返回博客
2026-09-04 08:00:02

分库分表:拆之前先想清楚这三件事,否则早晚要还债

分库分表:拆之前先想清楚这三件事,否则早晚要还债

很多团队把分库分表当成“高并发万能药”。单库扛不住了,拆;慢查询多了,拆;连接池满了,拆。拆完发现,跨库JOIN没法写,分布式事务搞不定,数据迁移差点丢数据——这才是噩梦的开始。

分库分表是“终极手段”,不是“首选方案”。动手之前,先回答三个问题:拆什么、怎么拆、拆完怎么迁

第一件事:拆之前,先确认“必须拆”

一个真实案例:某电商订单系统,高峰期单库写入TPS约5000,读QPS约2万,单库MySQL CPU已到80%。但排查发现,慢查询占60%——索引没建对,缓存命中率极低。团队花了三周优化索引和缓存,CPU降到40%,撑过了大促。

判断“必须拆”的标准很简单:

这三条都不满足,别拆。拆了等于给自己找事。

第二件事:拆的策略——选对分片键比选对中间件更重要

分片键选错,后患无穷。最常见的错误是:拿订单ID做分片,但业务查询都是按用户ID查的。结果每个查询都要路由到所有分片,性能比单库还差。

分片键选择的铁律:选“高频查询”的维度。 用户下单查订单,高频维度是用户ID,那就按用户ID分片。订单号作为分片键只在“按订单号查”场景高效,但电商系统里“查某用户的订单列表”才是高频。

分片算法有三个常见选项:

1. 哈希取模

shard_id = hash(user_id) % 16

优点:数据分布最均匀。缺点:扩容时几乎要全量迁移。16个库扩到32个,所有数据都要重新分布。

2. 范围分片

shard_id = user_id / 1000000  // 每100万用户一个库

优点:扩容方便,直接加库,已分配的数据不动。缺点:热点问题——新用户集中在最新分片,老分片空闲。

3. 一致性哈希

ring_position = hash(user_id)  // 落到哈希环上

优点:扩容只影响相邻节点,迁移量小。缺点:实现复杂度高,且依然有热点可能。

实战选择建议:

一个容易踩坑的地方: 哈希取模的分片数,最好选质数(如17、31),不要选2的幂。选2的幂,哈希低位分布不均,容易导致数据倾斜。这个坑不踩不知道,踩了数据分布一看就傻眼。

第三件事:平滑迁移——最容易被低估的环节

拆完库,数据还在老库。怎么迁?停机迁移最简单,但业务不允许。平滑迁移的方案,业内叫“双写迁移”,分三步走:

步骤1:老库和新库并行运行,业务写入同时发到两个库
步骤2:用数据同步工具(如Canal)把老库历史数据迁移到新库
步骤3:校验数据一致性,确认无误后,切换读流量到新库,最终下线老库

关键点有三处:

关键点1:双写的顺序。先写老库,再写新库。如果新库写失败,不影响主流程,只需要记录日志,后续异步补偿。反过来先写新库,老库写失败,主流程直接报错。

关键点2:历史数据迁移的校验。数据同步工具迁移完成后,必须做数据对账。最简单的做法:对每个分片,分别count老库和新库的行数,不一致就查差异。但count大表很慢,更实际的办法是抽样校验:按ID范围抽5%,比对字段值。

关键点3:切换流量要灰度。别一次性把全部读流量切到新库。先切5%的流量,观察慢查询和错误日志,确认稳定后再逐步提升到10%、50%、100%。这个过程可能需要几天,但安全第一。

这个方案的核心代价是:业务代码需要维护双写逻辑,相当于每个写操作要发两次。代码复杂度上升,且需要处理双写失败时的补偿。但这是平滑迁移的必然代价——不想停机,就得接受这段“脏活”。

演进路线:别想着一步到位

分库分表不是一次性动作,它是一条演进路径:

阶段1:单库单表 → 优化索引、加缓存,撑到极限
阶段2:单库分表 → 拆表不拆库,缓解单表压力
阶段3:分库分表 → 数据量再涨,库也拆开
阶段4:引入中间件 → ShardingSphere或MyCat,屏蔽分片路由细节
阶段5:单元化 → 按用户维度垂直拆分,每个单元独立部署

阶段2是很多团队忽略的过渡方案。 如果数据量过千万,但TPS不高,先拆表不拆库,成本低,不需要引入中间件,代码改动也小。等单库连接数或IO成为瓶颈,再走阶段3。

一个建议: 不要一开始就上中间件。中间件(如ShardingSphere)虽然屏蔽了分片细节,但也带来了新的复杂度:分布式事务、全局ID生成、跨分片聚合查询,都成了新问题。如果团队规模不大,能用手写分片逻辑(通过一个路由层封装)就先用着,等分片数超过8个再考虑中间件。

拆完之后的“债”怎么还

拆完分库分表,有些问题绕不开:

这些问题在拆之前就得想明白。拆完再想,代码已经写死了,改造成本翻倍。

一句话收尾

分库分表解决的是“单库物理极限”,不是“慢查询”;拆之前先优化索引和缓存,拆的时候选对分片键,拆之后平滑迁移——这三步走稳了,分库分表才能成为架构的加分项,而不是负债项。

下一步做什么: 拿你手头最慢的那张表,先做索引分析和缓存优化,跑一周看看效果。如果还扛不住,再画分片方案图,按本文的三步走评估一次。

本文关键词:分库分表、分片键、平滑迁移、双写、哈希取模