容量余量
维持被测容量余量使流量突增不致饱和宕机。
为什么
跑 95% CPU 的服务距宕机一条病毒推文 — 无 20% 流量突增、重试风暴或加 5% 负载部署的余量。容量余量是当前利用率与服务退化点间的缓冲,维持它(关键资源通常 30-50% 余量)是你能做的最便宜可靠性投资。陷阱是余量感觉浪费钱 — "我们付不需要的服务器"— 但 30% 过配成本是一次饱和宕机损收入和客户信任成本的一小部分。跟踪余量并在低于 30% 时告警的 团队在正常增长中抓容量问题,非在突增变宕机时。
何时使用
对每有状态资源(DB、缓存、队列)和每自动扩缩服务的基线。预期突增前(发布、营销、季节)审查。
如何做
1. 识别每资源饱和点 - DB:连接池耗尽、CPU >80%、磁盘 IOPS 限 - 缓存:驱逐率 >1%、内存 >90% - 队列:深度无界涨、消费者滞后增 - 服务:p99 延迟在某 QPS 急升("膝") 2. 测当前利用率 vs 饱和点 - headroom = (saturation_point - current_utilization) / saturation_point - 每资源仪表盘跟踪;余量 <30% 告警 3. 每资源类设余量目标 - 有状态(DB、缓存):30-50% 余量(难快扩需缓冲) - 无状态自动扩:20% 余量(自动扩缩器处理突增,只需基线缓冲) - 单实例(无 HA):50%+ 余量(无故障转移需退化余量) 4. 对余量侵蚀告警,非仅绝对利用率 - "DB CPU >70% 持续 1h" → 工单(余量 <30%,规划容量) - "DB CPU >85%" → page(余量 <15%,迫近饱和风险) - 跟踪趋势非快照 — 70% 每周升 1% 紧急 5. 从增长率 + 突增缓冲规划容量 - current × (1 + weekly_growth) × (1 + spike_buffer) = N 周后需容量 - 需要前订硬件/调大小,非告警触发时
示例
# 容量余量仪表盘(每资源)
# DB(Postgres):
db_cpu = 68% # 饱和 85% → 余量 = (85-68)/85 = 20% ⚠ <30%,工单
db_connections = 180/200 # 90% → 余量 = 10% 🔴 page
db_disk_iops = 12000/15000 # 80% → 余量 = 20% ⚠
# 缓存(Redis):
cache_memory = 78% # 驱逐 90% → 余量 = 13% ⚠
cache_eviction_rate = 0.3% # <1% 正常
# 告警规则:
- alert: DbHeadroomLow
expr: (85 - avg(db_cpu_pct)) / 85 < 0.30 # 余量 <30%
for: 1h
labels: { severity: ticket, team: platform }
annotations: { runbook: "https://rb/db-capacity-plan" }
# 容量规划(基于增长):
# current_qps = 500,周增长 = 2%,突增缓冲 = 50%(黑五)
# qps_8_周后 = 500 × 1.02^8 × 1.5 = 500 × 1.17 × 1.5 = 878
# → 第 8 周需 878 QPS 容量;现在订升级常见问题
- ⚠跑 90%+ "省钱"— 省的是一次饱和宕机成本的一小部分;余量是你能买的最便宜保险。
- ⚠对绝对利用率(CPU >80%)告警而非余量 — 100 连接池的 80% 没事,250 限 200 池的 80% 不行;跟踪余量。
- ⚠无增长率跟踪 — 你到 70% 订需 4 周到的硬件,届时你 88% 饱和。
- ⚠自动扩缩器藏基线余量问题 — 扩缩器不停加实例但 DB(不能自动扩缩)饱和;跟踪每资源非仅易的。
最佳实践
- ✓有状态资源(DB、缓存)维持 30-50% 余量因不能快自动扩缩;自动扩缩无状态服务 20% 通常够。
- ✓对余量(到饱和的边距)告警非绝对利用率 — 同百分比对不同池大小意味不同边距。
- ✓跟踪增长率并需前 N 周订容量,计采购提前期 — 别告警触发时订。
- ✓预期突增前(发布、黑五)预扩缩并压测确认余量;别依赖自动扩缩器在突增中救你。