容量规划做完,预算批不下来;预算批了,容量还是不够。这两句抱怨常出自同一次会议的两端:SRE 拿 QPS 曲线讲拐点,财务拿年度额度讲封顶,都说真话,用的却是两套语言,结论永远是"再评估一下"。
这篇不谈扩缩容,只谈责任归属:谁有权批、谁承担后果、承诺以什么形态给出,以及这些安排在什么情况下失效。
1. 两套语言与翻译的必要性
| 容量侧词汇 | 财务侧词汇 | 翻译丢什么 |
|---|---|---|
| P99、错误预算 | 服务等级、赔付条款 | 可靠性被压成一个赔付比例 |
| 峰值 QPS、并发数 | 单位成本、月度支出 | 峰值的短时性被抹成月均 |
| 预留、N+1 冗余 | 资本化、折旧 | 冗余被当成浪费而不是保险 |
翻译不是换单位,是把"技术必要性"转成"财务可比较量":多留 30% 余量 ≈ 每月固定支出涨几个点,换回某个量级的故障概率下降。这句说不出来,预算会只能靠职级吵架。
反过来,"按季度砍 15%"也要译成工程语言:砍冗余、缓存命中率,还是降级阈值?砍在哪层,决定它伤成本还是伤可靠性。
2. 三种责任模式与失效形态
| 模式 | 谁批 | 失效形态 |
|---|---|---|
| 集中审批 | 平台/财务统一批 | 审批者不承担延迟,倾向压低;业务学会先做大再砍 |
| 团队自治 | 团队自批自付 | 公共成本无人认领(网关、日志、监控) |
| 混合 | 平台批基线,团队批增量 | 基线僵化,新业务永远跑在例外里 |
三种都能用,区别在失效落在谁身上:集中审批推给业务(延迟),自治推给组织(公共成本漂移),混合推给流程(例外堆积)。选型判据:增长可预测、团队少 → 集中审批;业务线差异大 → 混合;平台已成瓶颈 → 自治 + 强制可见性。
3. 谁背超支,决定行为
| 责任安排 | 理性行为 | 后果 |
|---|---|---|
| 团队不背超支 | 按峰值上限申请,宁多勿少 | 利用率低,预算年年涨 |
| 团队全背超支 | 压余量、拖扩容、隐藏增长 | 故障率升,事故成本外部化 |
| 只背增量,且不进个人考核 | 优化自身用量、提前沟通 | 最接近可持续,依赖数据可信 |
第二行最危险:让团队全额承担超支,等于给可靠性定价——团队用降级、限流、拖延扩容省钱,省下的记自己账上,故障成本记用户账上。
可用做法是"背增量 + 可见性":团队对新增用量负责,超支只进团队级指标,不与个人绩效挂钩——前提是账单能按团队切分。
labels:
required: [team, service, env, cost_center]
unit_cost: 月度成本 / 成功请求数 # 分母口径须与 SLO 一致
shared: [gateway, observability, ci] # 公共成本按用量分摊
缺一个维度,账单只能整体看,责任划分就退化成"大家一起贵"。
4. 容量承诺的形态与成本结构
| 形态 | 成本结构 | 适用 | 主要风险 |
|---|---|---|---|
| 预留(包年/包月) | 固定支出、单价低 | 基线负载稳定 | 预测偏高即长期沉没 |
| 弹性(按量) | 变动支出、单价高 | 峰值、突发 | 峰值时段账单陡增 |
| 混合 | 固定 + 变动 | 多数在线业务 | 基线划分要持续维护 |
混合是常态,决策点是基线画在哪:画低了弹性吃掉折扣,画高了低谷期为空转付费。
# 预留回本月数:结构示意,单价按云厂商价目核对
def breakeven(reserved, ondemand, upfront, hours):
saving = (ondemand - reserved) * hours
return upfront / saving if saving > 0 else float('inf') # 与剩余生命周期一半比较
回本月数超过剩余生命周期一半就不划算:预测误差的期望损失已大于折扣收益。
5. 预算周期与业务周期的错配
| 错配 | 表现 | 缓解 |
|---|---|---|
| 年度预算 vs 季度增长 | 年中已超全年额度 | 季度滚动预测 + 额度可调 |
| 合约周期 vs 技术周期 | 三年合约锁死旧机型 | 分层承诺,短周期保弹性 |
根因是预算按日历切、负载按业务切:硬要对齐只会得到两种结果——预算永远滞后一个季度,或业务被预算节奏绑住。务实做法是承认两套节奏,用"年度总量 + 季度分配 + 月度监控"连接。
6. 突增流量的预算外通道
突增(活动、热点、故障转移)在预算里没有位置:不在预测,也不在额度。缺合法通道,团队只有两条路——违规扩容,或让服务降级。
{"emergency_budget": {
"trigger": "daily_cost > baseline*2.5 || severity <= 2",
"approver": "oncall_manager", "cap": "月额度 15%,超出需二级审批",
"post_hoc": "24h 内提交原因、影响面、是否转常态"}}
| 通道设计 | 触发条件 | 事后处理 |
|---|---|---|
| 预授权额度 | 单日支出超日常量级若干倍 | 24 小时内补单说明 |
| 无通道 | —— | 团队自行绕开,账目失真 |
事后处理不能省:没复盘,应急通道会变成常规通道;有复盘,突发支出反而成了容量预测的免费样本。
7. 余量就是保险:容量与可靠性的交换
| 余量策略 | 成本 | 买到什么 |
|---|---|---|
| 贴着均值跑 | 最低 | 无缓冲,抖动直接变故障 |
| N+1 | 中 | 单实例故障不掉容量 |
| 峰值 × 1.3 | 中高 | 吸收预测误差与短时突增 |
多留余量不浪费,是用可预测的固定支出买不可预测的故障损失。判断余量不看平均利用率,看两件事:降级路径是否验证过、余量的钱是否花在杠杆最大处(入口与数据库,而非离线任务)。
平均利用率低不等于浪费:峰值打满的入口集群是正常设计;峰值靠限流兜底,才是把风险转给用户。
8. 需求预测与误差来源
| 方法 | 依据 | 主要误差来源 |
|---|---|---|
| 历史外推 | 同比/环比 | 活动、竞品、渠道变化使历史失效 |
| 目标反推 | 增长目标 × 单位用量 | 目标乐观、单位用量假设过时 |
| 驱动因子模型 | 用户数 × 人均请求 | 人均请求随功能迭代漂移 |
误差都来自同一处:把过去的系数用到未来。所以预测产出不该是一个数,而是"区间 + 假设清单":区间定预留,清单一决定何时必须重算。
约定:给 P50 与 P90 两档,基线按 P50 买预留,差额走弹性。预测错了,错的是钱,不是可用性。
9. 评审节奏与触发条件
| 类型 | 频率 | 输入 | 输出 |
|---|---|---|---|
| 定期评审 | 季度 | 用量趋势、单位成本、预算偏差 | 下季额度与基线 |
| 事件驱动 | 触发式 | 大促、新功能、架构变更 | 临时额度与扩容计划 |
| 异常驱动 | 周 | 成本突增、利用率跌破阈值 | 归因与整改项 |
两类盲区不同:定期评审滞后于变化,事件驱动漏掉慢性漂移——每月涨 5% 最易被忽视,而慢性漂移比突增更贵,它从不触发告警。触发条件要写死:
# 成本斜率:近 7 天日均 / 30 天前日均 > 1.15
(sum(rate(cloud_cost_usd_total[7d])) / 7) / (sum(rate(cloud_cost_usd_total[7d] offset 30d)) / 7)
# 过度预留:连续 14 天利用率低于 0.25
avg_over_time(instance_cpu_utilization[14d])
第二条常被忘:过度预留与容量不足是同一问题的两端。
10. 超支归因的四个类别
| 类别 | 特征 | 处理方向 |
|---|---|---|
| 增长 | 单位成本不变、用量上升 | 正常,走预算增量 |
| 浪费 | 空闲资源、孤儿磁盘、未清快照 | 直接回收,最快见效 |
| 价格 | 单价变化、折扣到期、区域调整 | 重谈合约或迁移 |
| 设计 | 单位成本本身高(架构、调用次数) | 改架构,周期最长 |
顺序必须是增长 → 浪费 → 价格 → 设计:先排增长,否则会把业务增长当浪费砍;先清浪费,它不需架构改动;价格属外部;设计最慢但决定长期单位成本。
-- 单位成本异常:找出"请求没涨但账单涨"的服务
SELECT service, SUM(cost) / NULLIF(SUM(requests),0) AS unit_cost
FROM billing_daily WHERE day >= CURRENT_DATE - 30
GROUP BY service
HAVING unit_cost > (SELECT AVG(unit_cost) * 1.2 FROM baseline);
单位成本涨而请求量平,可排除增长,直接进"价格"或"设计"。
11. 度量
| 指标 | 定义要点 | 健康信号 |
|---|---|---|
| 预算偏差率 | |实际-预算|/预算,按季度看 | 窄区间波动,方向不总是一边 |
| 利用率 | 核心看峰值余量,离线看均值 | 分类看,不混算 |
| 单位成本 | 成本 / 成功请求或活跃用户 | 随规模上升而下降 |
| 容量事件次数 | 因容量导致的降级/限流 | 趋零,无"差点出事"的漏记 |
第一个指标要看方向:偏差恒正说明预算总偏低(申请时就在打折),恒负说明有人虚报。
12. 排错:账与容量对不上时
| 现象 | 原因 | 处理 |
|---|---|---|
| 账单涨了但用量没涨 | 单价变化、折扣到期、出口流量费 | 按 SKU 拆账单,先排价格类 |
| 预留利用率长期偏低 | 基线按峰值画而非 P50 | 重画基线,差额转弹性 |
| 突增后账目对不上 | 应急支出未进成本事件流 | 补埋点,强制事后登记 |
| 团队互相推诿超支 | 公共成本未分摊 | 先分摊网关/日志/CI,再谈责任 |
最后一行是盲区:应急支出如果没人记账,它就不存在于预算体系里,来年预测会系统性偏低。
13. 边界:正式责任划分何时是过度设计
| 场景 | 判断 | 替代做法 |
|---|---|---|
| 完全托管、按量计费 | 无预留决策 | 只设月度告警阈值 |
| 团队小到一人能看全账 | 流程成本高于误差成本 | 每周看一次账单 |
| 成本占营收比例极低 | 优化收益不抵人力 | 不做归因,只做上限告警 |
| 探索期、负载不可预测 | 预测与基线都不成立 | 全弹性,接受单价高 |
判据:当"算清这笔钱该谁出"的成本超过这笔钱本身,责任划分就退回"一个人盯账单"。
14. 自测
- 把"多留 30% 余量"翻译成财务语言,需要哪几个数?
- 团队全额承担超支会出现什么行为,为什么等于给可靠性定价?
- 混合承诺里基线画高、画低各付出什么代价?
- 年度预算与季度增长错配,最有效的缓冲结构是什么?
- 超支归因为什么要按"增长→浪费→价格→设计"排序?
- 预算偏差率只看幅度不看方向,会漏掉什么?