容量估算与压测
「这个系统能扛多少?」是系统设计面试的必问题,也是上线前的必答题。 估算不需要精确,需要量级正确。这篇给一套能当场算的公式和一张能背下来的参考表。
一、四个基本量
任何容量问题最终都落到这四个数上:
| 量 | 单位 | 决定什么 |
|---|---|---|
| QPS | 次/秒 | 需要多少台应用服务器 |
| 存储 | GB/TB | 需要多少磁盘、要不要分库分表 |
| 带宽 | Mbps | CDN、专线、出口带宽 |
| 连接数 | 个 | 文件句柄、线程/协程数、LB 规格 |
二、QPS 怎么估
从日活推峰值
日均 QPS = 日请求量 / 86400
峰值 QPS = 日均 QPS × 峰值系数日均 QPS = 日请求量 / 86400
峰值 QPS = 日均 QPS × 峰值系数峰值系数取 2~5(业务集中型取高,如打卡、抢购;全天均匀取低)。 再乘一个安全系数 1.5~2(应对突发和后续增长)。
例:日活 100 万,人均 50 次请求。
日请求 = 100万 × 50 = 5000 万
日均 QPS = 5000万 / 86400 ≈ 580
峰值 QPS = 580 × 4 ≈ 2300
规划容量 = 2300 × 1.5 ≈ 3500 QPS日请求 = 100万 × 50 = 5000 万
日均 QPS = 5000万 / 86400 ≈ 580
峰值 QPS = 580 × 4 ≈ 2300
规划容量 = 2300 × 1.5 ≈ 3500 QPS面试时把这三步念出来,比直接给一个数可信得多。
单机能力参考(量级,别当绝对值)
| 场景 | 单机 QPS(4C8G) |
|---|---|
| 纯内存计算 / 静态接口 | 1 万 ~ 3 万 |
| 一次 Redis 读 + 少量逻辑 | 5 千 ~ 1 万 |
| 一次 MySQL 主键查询 | 2 千 ~ 5 千 |
| 一次 MySQL 复杂查询 / 多表 | 200 ~ 800 |
| 一次跨服务 RPC 调用 | 1 千 ~ 3 千 |
| 一次大模型调用 | 1 ~ 20(受模型侧限制) |
反直觉但重要:瓶颈几乎总在 IO。CPU 打满前,数据库或下游服务已经先跪了。
三、存储怎么估
单行大小 ≈ 各字段字节数之和(varchar 按实际长度估,不算声明长度)
表大小 ≈ 单行大小 × 行数 × (1 + 索引开销 20%~50%)
实际占用 ≈ 表大小 × 副本数 × (1 + 冗余 30%)单行大小 ≈ 各字段字节数之和(varchar 按实际长度估,不算声明长度)
表大小 ≈ 单行大小 × 行数 × (1 + 索引开销 20%~50%)
实际占用 ≈ 表大小 × 副本数 × (1 + 冗余 30%)例:订单表,单行 500B,每天 100 万单,保留 3 年。
行数 = 100万 × 365 × 3 ≈ 11 亿
原始 = 11亿 × 500B ≈ 550 GB
算索引和冗余 ×1.5 ≈ 825 GB
单副本 825GB,主从两份 ≈ 1.7 TB行数 = 100万 × 365 × 3 ≈ 11 亿
原始 = 11亿 × 500B ≈ 550 GB
算索引和冗余 ×1.5 ≈ 825 GB
单副本 825GB,主从两份 ≈ 1.7 TB结论:单表 11 亿行必须分库分表(单表建议 1000 万~2000 万行,或单表 10GB 以内)。
冷热分离怎么算
一般 90% 的访问集中在最近 10% 的数据上:
- 热数据(近 3 个月):放 SSD / 高配库
- 冷数据(3 个月以前):放归档库或对象存储,按需回查
四、带宽怎么估
带宽(Mbps) = QPS × 单次响应大小(Byte) × 8 / 1e6带宽(Mbps) = QPS × 单次响应大小(Byte) × 8 / 1e6例:2000 QPS,平均响应 20KB。
2000 × 20KB × 8 / 1e6 ≈ 320 Mbps2000 × 20KB × 8 / 1e6 ≈ 320 Mbps如果响应是图片/视频,先上 CDN,别让源站扛。
五、压测怎么做
工具
| 工具 | 适合 |
|---|---|
| wrk / hey | 压单个 HTTP 接口,轻量 |
| JMeter | 复杂场景(登录、参数关联、断言) |
| k6 | 脚本化、可进 CI |
| ab | 最简单,别用于生产前评估(单线程模型不准) |
四个必须看的指标
| 指标 | 含义 | 关注点 |
|---|---|---|
| QPS / TPS | 吞吐 | 拐点在哪 |
| P99 延迟 | 长尾 | 平均延迟没意义 |
| 错误率 | 超时/5xx | 拐点前会先抬头 |
| 资源水位 | CPU/内存/连接数 | 谁先满谁就是瓶颈 |
找拐点:阶梯加压
并发 10 → 50 → 100 → 200 → 400 → 800
每档跑 3~5 分钟,记录 QPS / P99 / 错误率 / CPU并发 10 → 50 → 100 → 200 → 400 → 800
每档跑 3~5 分钟,记录 QPS / P99 / 错误率 / CPU画出来会看到:QPS 先线性上升,到某点开始变平而 P99 陡增 —— 那个点就是容量拐点,规划时取它的 70%。
压测的五个坑
- 数据量不对:空表压出来的 QPS 是假的,先灌到生产量级(至少百万级)。
- 没预热:JVM 没 JIT、连接池没建满,前 30 秒数据要丢掉。
- 压测机是瓶颈:压测机 CPU 打满或网络打满,测出来的是压测机的能力。
- 只压单接口:真实流量是混合的,要按比例配比。
- 没看下游:应用没事,数据库连接池先爆了。
六、容量规划表(面试可直接画)
| 项 | 估算值 | 结论 |
|---|---|---|
| 峰值 QPS | 3500 | 应用 4 台(单机 1000,留 30% 余量) |
| 存储 3 年 | 1.7 TB | 分 8 库 16 表,或按用户 ID 分片 |
| 带宽 | 320 Mbps | 上 CDN + 压缩 |
| 连接数 | 峰值 8 万 | LB / 网关按 10 万连接规划 |
| 缓存 | 热点 20% | Redis 16GB × 主从 |
七、速查
| 问题 | 答案 |
|---|---|
| 日活怎么换 QPS | 日请求/86400 × 峰值系数(2~5) × 安全系数(1.5~2) |
| 单机 MySQL 能扛多少 | 主键查询 2k~5k QPS,复杂查询几百 |
| 单表多大要分表 | 1000 万~2000 万行,或 10GB |
| 带宽怎么算 | QPS × 响应大小 × 8 |
| 压测看什么 | QPS 拐点 + P99 + 错误率 + 资源水位 |
| 容量留多少余量 | 拐点的 70% 作为规划值 |
| 压测最常见的假数据 | 空表、没预热、压测机瓶颈 |
Cao Note