1170 字
约 3 分钟
4
S08-A01 · 分库分表:为什么、怎么分、带来什么

适用读者:单表上千万行、或正在决定要不要分库的人。
前置:S08-J01(分页与深翻)。
覆盖旧文:1824(158) 2649(146) 1099(114) 2661(110) 1098(78) 1103(70) 2402(6) 503(43) = 725 点。
覆盖扩展:E-S08-005(分片键与路由)、E-S08-006(跨库事务)。
上一篇:S08-J04 · 批量操作与 SQL 注入器
下一篇:S08-A02 · 多数据源。


1. 一句话结论

分库分表是"用复杂度换容量"的最后手段。先试索引/归档/读写分离,三者都不够时再分。

手段 成本 收益
加索引/优化 SQL 低 常能解决 80% 的慢查询
冷热分离/归档 中 表变小,查询变快
读写分离 中 分担读压力
分库分表 高 突破单机容量/连接数

2. 什么时候真的需要(A-1824/A-2402)

信号 阈值(经验)
单表行数 千万级起(不是绝对)
单表磁盘 数十 GB~百 GB
写入 QPS 单库写入瓶颈(主库 CPU 打满)
连接数 单实例连接数上限

判据:"是数据量的问题,还是 SQL/索引的问题?" 先证明后者不是主因。


3. 分片键怎么选(E-S08-005)

方案 优点 缺点
按用户 ID 同用户数据聚合 按时间/商家查询要扫全部分片
按时间(月) 归档方便 热点集中(当前月)
按哈希 分布均匀 范围查询要广播

核心矛盾:分片键决定了"哪些查询能路由到单片"。选错 → 大量跨分片查询。

判据:"80% 的查询带这个字段吗?" 带 → 可做分片键。


4. 分片数量为什么常取 2 的幂(A-1103)

原因 说明
取模定位 hash % 2^n 可用位运算
扩容方便 翻倍扩容时可用"高低位拆分"(与 HashMap 扩容同理,S04-J02)
均衡 2 的幂更易均分

注意:取模分片在扩容时几乎全量迁移;一致性哈希/预分片(如 1024 逻辑分片)能缓解。


5. 分完之后的新问题(A-1099/A-2661)

问题 表现 解决
跨库 JOIN 无法直接 join 冗余字段/宽表/应用层拼装
分布式事务 跨库写不一致 本地消息表/TCC/Saga(S17)
分页 全局分页要汇总各分片 游标分页/搜索引擎
全局唯一 ID 自增 ID 冲突 雪花算法/号段模式
聚合统计 count/sum 要合并 预聚合/OLAP 库
扩容迁移 数据重分布 双写 + 校验 + 切流

这张表就是"分库分表的真实代价"——旧文讲了"为什么分",这张表讲"分完要还什么债"。


6. 迁移与回滚(可交付)

阶段 动作 回滚
双写 新老表同时写 关掉新写
校验 逐条比对(抽样 + 全量) 停止双写
读切换 灰度读新表(1%→100%) 切回旧表
下线旧表 观察 1 个月后 保留备份

铁律:每一次"分"都必须有"双写 + 校验 + 灰度"三件套,否则迁移即事故。


7. 五个误区

误区 真相
"分库分表能解决所有性能问题" 先看索引与 SQL
"按时间分表最均匀" 当前分片是热点
"分了就不用管 JOIN" 跨库 JOIN 要应用层解决
"分片数随便定" 影响扩容成本与均衡
"扩容就是加机器" 要迁移数据

8. 自检(架构师版)

  1. 分库分表之前该先试哪三件事?
  2. 分片键的判据是什么?选错会怎样?
  3. 为什么分片数常取 2 的幂?
  4. 分完之后必须解决的五个问题?
  5. 迁移的三件套是什么?

9. 下一篇

S08-A02 · 多数据源与动态切换

分库之后必然遇到"切换数据源"——下一篇讲 AbstractRoutingDataSource 与它和事务的冲突。


本篇属于系列《S08 · MyBatis 持久层》。旧文来源:A-1824/2649/1099/2661/1098/1103/2402/503;扩展点 E-S08-005/006。

S08-A01 · 分库分表:为什么、怎么分、带来什么
https://www.clxhxhhr.top/posts/5293/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。