系统容量评估:从 QPS 到资源清单
CrimsonCastle
7 min read
判断:容量评估不是拍脑袋说"能扛一万",而是从业务峰值 QPS 出发,逐层换算成 CPU、内存、数据库连接、带宽和存储的明确数字,再留出余量。缺了这层换算,扩容就成了"感觉不够就加机器",要么浪费要么雪崩。
从 QPS 到单机吞吐
先估单实例能扛多少。假设一个接口平均处理耗时 20ms,单线程串行理论吞吐 1000/20 = 50 QPS;但服务是多线程,设工作线程 200,理想吞吐约 200 / 0.02 = 10000 QPS(忽略锁与 IO 等待)。实际受 GC、下游依赖、锁竞争影响,经验上取理想值的 30%~60% 作为可用吞吐。这个折扣不是随便取,要靠压测校准,没有压测的折扣就是猜测。
用 Little 定律看并发
Little 定律:L = λ × W。L 是系统中平均并发数,λ 是到达率(QPS),W 是平均驻留时间(秒)。若 QPS=1000、平均处理 0.05s,则平均并发 = 1000 × 0.05 = 50。这 50 个并发会占用 50 个线程/连接,据此推算线程池与连接池下限。连接池上限要高于峰值并发,否则请求在等连接而非在处理。
调用链会把压力放大
一个对外接口可能内部调用 3 个下游服务,每个下游又查库。对外 5000 QPS,落到某个被多次调用的下游可能是 15000 QPS。容量评估必须顺着调用链逐层叠加,而不是只算入口。缺了这一层,往往出现"入口扛住了、某下游被放大压垮"的诡异故障。
逐层摊到资源
以峰值 5000 QPS 的读多写少服务为例,假设读缓存命中率 90%:
- 落到数据库的真实读 QPS ≈ 5000 × 10% = 500。
- 单库实例经验上稳定扛 2000~5000 简单查询 QPS(视语句复杂度),单库够,但为可用性和余量建议主从各一。
- 缓存层需承受 5000 × 90% = 4500 QPS 读,单 Redis 实例轻松覆盖,但需评估内存:缓存条目数 × 单条大小。
- 应用层:按单实例可用吞吐(如 3000 QPS,理想 10000 取 30%)算,至少 2 实例,建议 3 留余量。
数据库连接数:若每个请求占用连接平均 0.02s,500 QPS 需 500 × 0.02 = 10 个连接;但要有突发和空闲缓冲,连接池通常开到峰值并发的 1.5~2 倍。
把数字变成资源清单
| 资源 |
计算依据 |
评估值 |
建议(含余量) |
| 应用实例 |
5000 / 3000 可用 |
2 |
3 |
| 数据库 |
500 读 + 写 |
1 主 |
1 主 1 从 |
| 缓存内存 |
条目数×大小 |
4 GB |
8 GB |
| 带宽 |
QPS×平均响应体 |
假设 50 MB/s |
100 MB/s |
| 存储/天 |
写入量×保留期 |
假设 20 GB/天 |
按 30 天 + 备份 |
所有量化都基于"假设"和"经验上"的区间,真实值要靠压测校正。表格把模糊的"扛不扛得住"变成可采购、可验收的清单。
余量不是浪费
评估值往往取峰值,但峰值不是日常。余量要覆盖:突发流量(大促、热点事件)、实例故障(一台挂了其余顶上)、运维操作(滚动发布时单实例承载能力下降)。经验上预留 30%~50% 余量,而不是精确匹配峰值。
一个跨服务的容量推演
假设活动页峰值 8000 QPS,页面聚合服务要调三个下游:商品服务(每请求 1 次)、推荐服务(每请求 1 次)、库存服务(每请求 2 次,因为要查两个仓)。则下游压力约为:商品 8000、推荐 8000、库存 16000 QPS。若库存服务单实例可用 4000 QPS,至少需要 4 实例(不含余量);推荐服务若带缓存命中 80%,真实落库约 1600 QPS,单实例够用。入口的 8000 QPS 若单实例可用 3000,需 3 实例,建议 4 到 5 含余量。
数据库侧:所有下游最终汇到几张核心表。假设核心读总 QPS 经缓存后剩 3000,单库 5000 简单查询可扛,但写(下单、扣库存)峰值假设 1000 QPS 且要求事务,单主库写能力要覆盖,主从分离只解决读、不解决写。写瓶颈要么提升单库写吞吐(固态盘、批处理),要么分库分表,容量评估必须分清读扩展和写扩展两条路。
容器与 CPU 的申请
应用实例数定了后,还要落到 CPU 与内存申请。若一个实例压测下在 1500 QPS 时 CPU 用到 1.5 核,留 30% 余量则申请 2 核;内存看常驻堆加堆外,压测稳态内存才是申请依据,而非启动瞬时峰值。容器上限设得过高浪费、过低触发驱逐,要基于真实压测数据而非拍脑袋。
容量评估要迭代而非一次定稿
容量评估不是上线前做一次就结束。每次大促、每次新功能上线、每次依赖变更,都应重算。把评估过程脚本化:输入峰值 QPS、各接口耗时、缓存命中率,输出资源清单,比每次手工算更不容易漏项。评估结果的"余量水位"要持续监控——实际 CPU、连接数、带宽用量距评估上限还有多少,是扩容决策的直接依据。
常见的容量误判
把"单机压测峰值"直接当"单实例容量":压测环境和生产环境网络、磁盘、上下游都不一样,直接套用会偏乐观。正确做法是压测得到可用吞吐系数,再结合生产观测校正。另一个误判是只看平均资源用量:容量看的是峰值与分位,平均值在峰值面前没有参考价值。
容量评估的输出要可执行
资源清单最终要落到采购或编排系统里:多少实例、什么规格、主从几台、带宽包多大。清单里每一项都要有"评估值"和"含余量建议值"两列,前者是理论最小,后者是实际申请。只给一个模糊数字,运维没法直接操作;给出可执行清单,扩容才有依据。
容量评估还要考虑数据增长曲线:今天 5000 QPS 的资源,三个月后日活翻倍是否还够?把"未来一段时间的增长假设"写进评估文档,比只看当下更稳。增长假设同样基于经验与业务规划,而非精确预测。
踩坑清单
拿均值当容量依据:日常 100 QPS,峰值可能 5000。必须按峰值或分位数(P99)评估,而非平均值。
忽略调用链放大:入口 5000 QPS 内部放大到下游 15000,只扩入口不扩下游,瓶颈照旧。沿调用链逐层换算。
忽略下游瓶颈:应用层扩到 10 台,数据库还是 1 台,瓶颈没解除,加机器只是加成本。
只算计算不算存储和带宽:CPU 够但磁盘 IO 打满、带宽跑满,一样崩。三项都要进清单。
估完不压测:所有系数都是假设,上线前用真实流量模型压测校正,否则余量可能是负数。
没有降级预案兜底:评估总有误差,容量临界时靠降级(砍非核心、限流)争取时间,而不是硬扛。
1 view
0 likes
0 comments