P85 分库分表还在拍脑袋定数量?小心系统直接崩!
面试题:分库分表怎么定分片数量?为什么不能拍脑袋?
1. 分片数量怎么定(核心公式)
先算单表容量上限,再倒推分片数:
text
预估总数据量(如 5 年 10 亿行)
单表合理容量(如 500 万 ~ 2000 万行,或单表几个 GB)
分片数 = 总数据量 ÷ 单表容量(再乘冗余系数)例:10 亿行 ÷ 1000 万行/表 = 100 个分片;再考虑增长冗余,可以按 128 或 256 提前规划。
2. 拍脑袋的后果
分片太少
- 单表涨太快,很快超过容量 → 又要扩容;
- 扩容是灾难:数据要 rehash 迁移,停机或双写,成本极高;
- 大表 DDL、备份、查询性能全部劣化。
分片太多
- 每片数据太少(如每表几十万行),查询要跨很多分片,聚合成本高;
- 连接数、连接池、内存被分片数量放大;
- 运维复杂:建表、监控、迁移都是 N 倍工作;
- 分片数不是越多越好。
3. 规划要点
- 按长期容量规划:按 3~5 年数据量预估,宁可多分不可少分(扩容代价大);
- 考虑单表增长速率:按峰值写入量倒推;
- 2 的幂:分片数用 2^n(如 16/32/64/128),取模运算高效(hash & (n-1)),方便扩容(翻倍迁移);
- 分库分表配合:分片同时考虑库的写入能力(连接数、IO);
- 预留扩展方案:一致性哈希(虚拟节点)或两级路由(先路由到组再路由到表)。
4. 加分点
- 说出"取模分片扩容要翻倍迁移"的痛点,以及一致性哈希减少迁移量的原理;
- 提到分片键选择:必须按查询最多的维度(如 user_id/order_id),否则全分片扫描;
- 追问"到底 500 万还是 2000 万":取决于行宽和访问模式,压测验证,不是固定值;
- 数据量没那么大时别过早分库分表,增加复杂度。
一句话总结
分片数量 = 长期数据总量 ÷ 单表合理容量(留冗余),尽量用 2 的幂便于取模和翻倍扩容;分太少扩容灾难,分太多聚合与运维成本暴涨,核心是按容量规划、留扩展余地、选好分片键。