Skip to content

P85 分库分表还在拍脑袋定数量?小心系统直接崩! ​

面试题:分库分表怎么定分片数量?为什么不能拍脑袋?

1. 分片数量怎么定(核心公式) ​

先算单表容量上限,再倒推分片数:

text
预估总数据量(如 5 年 10 亿行)
单表合理容量(如 500 万 ~ 2000 万行,或单表几个 GB)
分片数 = 总数据量 ÷ 单表容量(再乘冗余系数)

例:10 亿行 ÷ 1000 万行/表 = 100 个分片;再考虑增长冗余,可以按 128 或 256 提前规划。

2. 拍脑袋的后果 ​

分片太少 ​

  • 单表涨太快,很快超过容量 → 又要扩容;
  • 扩容是灾难:数据要 rehash 迁移,停机或双写,成本极高;
  • 大表 DDL、备份、查询性能全部劣化。

分片太多 ​

  • 每片数据太少(如每表几十万行),查询要跨很多分片,聚合成本高;
  • 连接数、连接池、内存被分片数量放大;
  • 运维复杂:建表、监控、迁移都是 N 倍工作;
  • 分片数不是越多越好。

3. 规划要点 ​

  1. 按长期容量规划:按 3~5 年数据量预估,宁可多分不可少分(扩容代价大);
  2. 考虑单表增长速率:按峰值写入量倒推;
  3. 2 的幂:分片数用 2^n(如 16/32/64/128),取模运算高效(hash & (n-1)),方便扩容(翻倍迁移);
  4. 分库分表配合:分片同时考虑库的写入能力(连接数、IO);
  5. 预留扩展方案:一致性哈希(虚拟节点)或两级路由(先路由到组再路由到表)。

4. 加分点 ​

  • 说出"取模分片扩容要翻倍迁移"的痛点,以及一致性哈希减少迁移量的原理;
  • 提到分片键选择:必须按查询最多的维度(如 user_id/order_id),否则全分片扫描;
  • 追问"到底 500 万还是 2000 万":取决于行宽和访问模式,压测验证,不是固定值;
  • 数据量没那么大时别过早分库分表,增加复杂度。

一句话总结 ​

分片数量 = 长期数据总量 ÷ 单表合理容量(留冗余),尽量用 2 的幂便于取模和翻倍扩容;分太少扩容灾难,分太多聚合与运维成本暴涨,核心是按容量规划、留扩展余地、选好分片键。

基于 VitePress 重建