老计聊SRE 04:Error Budget,允许出错是为了跑得更快
本系列的示例应用和脚本开源在 GitHub(仓库地址见文末)。本篇所有数据来自对示例应用的真实压测。
本篇目标
上一篇我们定了 SLO:可用性要达到 99%。这句话听着是在讲"要多可靠",但它还藏着另一层意思,反过来读一遍你就懂了。
可用性 99%,意思是允许 1% 的请求失败。
这 1% 不是意外,是你主动留出来的空间。它就是这一篇的主角:Error Budget,错误预算。学完本篇你将掌握:
- Error Budget 是什么,它和 SLO 是什么关系
- 为什么它能把"稳定"和"快"这对矛盾变成可以算的账
- 怎么算预算消耗,用真实数据看预算烧得快还是慢
- 预算快烧完时,团队该怎么做决策
一、SLO 的另一面,就是错误预算
先把上一篇接上。我们定了 SLO:可用性 99%。
- 达标线:99% 的请求要成功。
- 反过来:1% 的请求允许失败。
这 1% 就是错误预算。它是一段时间内,你"可以用掉"的失败额度。
打个比方。SLO 像是你给自己定的每月开销上限,错误预算就是这个上限里"可以花的钱"。你不用把钱死死攥住一分不花,那样反而失去了钱的意义。你该做的是把这笔预算花在刀刃上:发新版本、做变更、承受一些偶发抖动。只要月底别超支就行。
关键转变在这:失败不再是"绝对不能发生的坏事",而是"一种有限的、可以规划使用的资源"。这是错误预算带给 SRE 最重要的思维转变。
SLO 99% 的另一面,就是 1% 的错误预算
二、它解决的是一个老掉牙的矛盾
做过线上系统的都熟悉这个场景。
- 开发想快点发新功能,多迭代,多上线。
- 运维想稳,最好啥都别动,一动就可能出事。
两边天天吵,谁也说服不了谁,因为大家吵的是立场,不是事实。
错误预算的高明之处,是把这场立场之争,变成了一道算账题:
- 预算还很充足:说明系统很稳,那就大胆发版、快速迭代,别浪费了这份稳定。花不完的预算不奖励你,不如拿去换迭代速度。
- 预算快烧完了:说明最近故障或变更太多,该踩刹车了,停下来先把稳定性搞回来,别再冒险上线。
你看,该快还是该稳,不再靠谁嗓门大,而是看预算这个数字。它给了开发和运维一个共同的、客观的裁判。这也是为什么说错误预算是 SRE 里最能落地的机制之一。
三、怎么算:预算是有单位的
错误预算不是一个模糊的说法,它能算出具体的量。
假设我们按月看,一个月大约有 30 天。SLO 是可用性 99%,那么错误预算就是 1%。
换算成时间(以时间型SLO粗算):
- 一个月约 43200 分钟
- 1% 的预算 = 432 分钟,大约 7.2 小时
也就是说,这个月你总共有约 7.2 小时的"失败额度"可以用。发版翻车、偶发故障、依赖抖动,消耗的都是这 7.2 小时。用完了,就意味着违约。
如果按请求算更直观:这个月如果有 100 万个请求,1% 的预算就是 1 万个请求可以失败。每失败一个,预算少一个。
预算是有单位、能相减的。这就是它能拿来做决策的前提。
四、动手:看预算烧得快还是慢
光有总额没用,关键是消耗速度。我们用真实数据看看,同一个服务在不同状态下,预算是怎么被消耗的。
先回顾我们的 SLO:可用性 99%,也就是错误率的红线是 1%。
先看稳态。服务正常跑的时候,压测 1000 个请求的真实结果:
稳态基线: 可用性 99.90% 错误率 0.100%稳态错误率只有 0.100%,而我们的预算红线是 1%。这意味着什么?
平时的消耗速度,只有预算允许速度的十分之一。换句话说,只要服务保持这个健康水平,你的预算烧得非常慢,富余得很。这些富余,就是你可以放心拿去发版、迭代的底气。
再看服务变差时。还记得上一篇的三档数据吗,把错误率并排放一起看:
| 状态 | 错误率 | 相对1%预算红线 | 预算消耗速度 |
|---|---|---|---|
| 稳态基线 | 0.100% | 远低于红线 | 极慢,预算充裕 |
| 健康 | 0.40% | 低于红线 | 慢,仍有富余 |
| 一般 | 2.20% | 超过红线一倍多 | 快,预算在净流失 |
| 较差 | 6.20% | 超红线6倍 | 极快,几下就见底 |
不同错误率下,预算消耗速度天差地别
这张表把"决策"两个字说透了。
稳态和健康状态下,错误率远低于 1% 红线,预算烧得慢、还在攒,团队可以放心发版。
可一旦掉到"一般状态",错误率 2.20%,已经是红线的两倍多。这时候预算不是在攒,是在净流失,而且流失得比允许的快。要是放着不管继续发版,预算很快就会见底,然后就是 SLO 违约。
这时候错误预算就替你做了决策:停止发新功能,把资源转去修稳定性。不用吵,数字摆在这。
五、预算烧完了,怎么办
假设这个月预算真的烧完了,SLO 眼看要违约,该怎么做。
一个成熟团队通常会触发所谓的"错误预算策略",常见的做法是:
- 冻结发布:暂停一切非必要的新功能上线,只允许修复稳定性的变更。既然预算超支了,就不能再往里花钱。
- 优先级转向:把团队精力从"做新东西"转到"提高可靠性",直到预算回到健康水平。
- 复盘根因:预算为什么烧这么快,是某次发布引入的,还是某个依赖不稳,找到并解决。
这套策略之所以有用,是因为它是事先约定好的,而不是出事了临时拍脑袋。开发和运维都提前认这个规则:预算够就放开跑,预算超就一起踩刹车。规则代替了扯皮。
六、几个容易踩的误区
- 误区一:把预算当成"必须用完的 KPI"。它是上限,不是任务。烧得慢是好事,说明系统健康,不是浪费。
- 误区二:只在月底才看预算。那时候超支了也晚了。预算要持续监控,最好能看到实时消耗速度,快烧完之前就预警。这其实就引出了下一篇的告警。
- 误区三:预算一超就无脑冻结。冻结是手段不是目的,得结合业务判断。核心大促期间的取舍,和平常不一样。规则要定,但不是死板执行。
七、从"额度"到"警报"
我们现在能算预算、能用预算做决策了。但第六节留了个尾巴:预算不能等到月底才看,得持续盯着消耗速度,快烧完之前就得有人知道。
那"有人知道"靠什么?靠告警。而且不是那种服务器 CPU 高了就响的老式告警,而是基于错误预算消耗速度的告警,烧得越快、越接近超支,告警越紧急。
怎么设计这样的告警,才能既不漏报、又不被没完没了的告警淹没,这是下一篇的主题。
预算要实时盯着烧的速度,快见底前就得报警
八、小结
- SLO 99% 的另一面就是 1% 的错误预算,失败从"绝对禁止"变成"可规划使用的资源"
- 错误预算把"求快"和"求稳"的立场之争,变成看数字的算账题
- 预算有单位、能相减:99% 的月度 SLO 约等于 7.2 小时或按请求的失败额度
- 真实数据看消耗速度:稳态错误率仅 0.100%,预算烧得慢;掉到一般状态 2.20% 就在净流失,该踩刹车了
- 预算烧完触发事先约定的策略(冻结发布、转向可靠性),用规则代替扯皮
- 预算要实时监控,快见底前预警,这就引出了下一篇的告警
下一篇:告警不是越多越好,基于错误预算燃尽率的告警哲学,怎么配才既不漏报又不吵死人。
参考链接
- 本系列开源仓库(示例应用 + 压测脚本):https://github.com/Jich1123/sre-aws-lab
- Google SRE Book - Embracing Risk(错误预算):https://sre.google/sre-book/embracing-risk/
- Google SRE Workbook - Implementing SLOs(错误预算策略):https://sre.google/workbook/implementing-slos/
- Google SRE Book - Service Level Objectives:https://sre.google/sre-book/service-level-objectives/