基于SLO告警(Part 2):为什么使用MWMB方法

songjiayang · · 2213 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

本篇文章为《基于 SLO 告警》系列文章第2篇,主要讲解基于 SLO 告警一般使用方法以及为什么要使用多窗口多燃烧率(MWMB)的方式。 对于基于 SLO 告警的一些基础概念,大家可以参考系列文章第1篇。 注意: - 文章大部分内容来自 Google 网站可靠性工作手册第5章,右下角可直接查看原文。 - 示例中以 Prometheus rules 为例。 ## 方法1:错误率≥SLO阈值 这种方法是大家最容易想到的,直接看最近一个较小时间窗口内(例如10分钟)目标错误率是否超过 SLO 阈值,如果超过即触发告警。 例如,30天的SLO为99.9%,过去10分钟内的错误率 ≥0.1% 时发出警报: ``` - alert: HighErrorRate expr: job:slo_errors_per_request:ratio_rate10m{job="myjob"} >= 0.001 ``` job:slo_errors_per_request:ratio_rate10m 指标可以使用 Prometheus 的 record rule 生成。 针对这种情况,假如服务 100% 中断大约 0.6s (10m*0.001)即可触发告警。 这种方法最大的问题是精度低,假如我们真的有一个服务,每隔10分钟就中断 0.6s,这意味着我们每天最多可以收到 144(24*6)个告警信息。即使我们什么都不做,依然能够满足 99.9% 的 SLO 目标。 ## 方案2:增加观察窗口 方案 1 中我们使用了一个较小时间窗口(10分钟),这样可能会因为服务抖动导致频繁告警,为了降低告警频率,我们可以适当增加错误指标观察的时间窗口,比如变为36小时(占30天错误预算 5%)。 对应的告警规则为: ``` - alert: HighErrorRate expr: job:slo_errors_per_request:ratio_rate36h{job="myjob"} > 0.001 ``` 此时当业务 100% 中断大约2分钟10秒(36h*0.001)即可触发告警。 这种方法最大的问题是告警重置时间较长,假如业务 100% 中断2分钟10秒后,业务马上 100% 恢复,我们仍然要等到36小时后,才能收到告警恢复的通知。 ## 方案3:告警持续性检测 这种方案主要使用一个较短的时间窗口,并观察其告警状态持续性,对应 Prometheus 中的告警规则就是使用 `for` ,比如: ``` - alert: HighErrorRate expr: job:slo_errors_per_request:ratio_rate1m{job="myjob"} > 0.001 for: 1h ``` 这种方法可以解决方案1中每隔 10m分钟中断0.6s 导致频繁告警的情况,又可以解决方案 2 中告警重置时间久的问题。 但这种方法也有一个致命问题,就是无法识别问题严重性,100% 错误率和 0.2% 错误率都需要持续1小时才能收到告警。 以1h 为例,假如 100% 中断的情况,当我们收到告警的时候,已经消耗了30天错误预算的 140%(60/43)。 ## 方案4:基于单一燃烧率 前面3种方案都采用固定时间窗口和固定阈值的方式,为了改进方案,我们很自然想到基于错误预算燃烧耗率的方法,针对不同燃烧率我们可以配置不同告警级别,消耗越快,告警级别越高。 燃烧率与耗尽时间的关系如表格: |燃烧率 |30 天 99.9% SLO的错误率 | 耗尽时间| |--- | --- | ---| |1|0.1%|30天| |2|0.2%|15天| |10|1%|3天| |1000|100%|43分钟| 那么我们该使用怎样的燃烧率呢? 举个例子,在1小时内燃烧了30天错误预算的5%,这就需要触发告警了,此时可以得到燃烧率为 36 (30*24*0.05/1)。 其告警规则为: ``` - alert: HighErrorRate expr: job:slo_errors_per_request:ratio_rate1h{job="myjob"} > 36 * 0 ``` 这种方法虽然解决前面提到的一些误报和恢复重置时间长的问题,但假如服务的燃烧率恰好只有35,意味着 20.5小时将消耗完所有的错误预算,而且您收不到任何告警。 ## 方案5:基于多个燃烧率 方案4中只有一个固定的消耗率,针对固定 35 燃烧率的问题,我们可以使用多个燃烧率来避免,不同燃烧率可以对应不同告警级别。 比较建议的时间窗口和燃烧率,消耗的 SLO 百分比对照表如下: |消耗 SLO 预算 |时间窗口 |燃烧率 |通知方式| |--- | --- | ---|---| |2%|1小时|14.4|呼叫| |5%|6小时|6|呼叫| |10%|3天|1|故障单| 告警规则配置为: ``` expr: ( job:slo_errors_per_request:ratio_rate1h{job="myjob"} > (14.4*0.001) or job:slo_errors_per_request:ratio_rate6h{job="myjob"} > (6*0.001) ) severity: page expr: job:slo_errors_per_request:ratio_rate3d{job="myjob"} > 0.001 severity: ticket ``` 这种方式能够解决方案4中的问题,但同一现象可能会触发多条告警,这意味着您需要更智能的告警抑制手段。 例如,五分钟内消耗了10%的预算,也意味着六小时内消耗了5%的预算,一小时内消耗了2%的预算,所以您可能会同时收到3条不同告警信息。 ## 方案6:多窗口、多燃烧率 我们继续在方案5之上进行迭代,思路很简单,确保当前服务仍在不断消耗预算的时候才进行告警。 为此我们需要增加一个短时间观察窗口,一般短窗口的时间为长窗口的时间的1/12,只有两个时间窗口燃烧率都满足条件,才进行告警通知。 99.9% SLO警报配置的推荐参数表为: |消耗 SLO 预算| 长期窗口| 短期窗口| 燃烧率| 通知方式| |--- | --- | ---|---|---| |2%|1小时|5分钟|14.4|呼叫| |5%|6小时|30分钟|6|呼叫| |10%|3天|6小时|1|故障单| 所以最后告警规则配置大致为: ``` expr: ( job:slo_errors_per_request:ratio_rate1h{job="myjob"} > (14.4*0.001) and job:slo_errors_per_request:ratio_rate5m{job="myjob"} > (14.4*0.001) ) or ( job:slo_errors_per_request:ratio_rate6h{job="myjob"} > (6*0.001) and job:slo_errors_per_request:ratio_rate30m{job="myjob"} > (6*0.001) ) severity: page expr: ( job:slo_errors_per_request:ratio_rate24h{job="myjob"} > (3*0.001) and job:slo_errors_per_request:ratio_rate2h{job="myjob"} > (3*0.001) ) or ( job:slo_errors_per_request:ratio_rate3d{job="myjob"} > 0.001 and job:slo_errors_per_request:ratio_rate6h{job="myjob"} > 0.001 ) severity: ticket ``` 好了,到此我们想要的最终方法已经有了,即采用多窗口多燃烧率(MWMB)的方式。 ## 总结 在基于 SLO 设计告警的时候,我们尽量采用 MWMB 的方法,它在告警及时性、告警重置恢复时间、误报、漏报都做了较好权衡。 但由于使用 MWMB 方法,对应的告警规则更为复杂,这给我们编写和维护规则配置文件带来了挑战。所以在实际工作中应该尽可能将其自动化,只需编写对应服务 SLO,即可按照 MWMB 方法,自动生成对应的告警规则(Prometheus alert/record rules)。 关于自动化部分我们会在后续实战文章中进行讲解,敬请期待。 - 基于 SLO 告警(Part 1):基础概念 - 基于 SLO 告警(Part 2):为什么使用 MWMB 方法 - 基于 SLO 告警(Part 3):开源项目 sloth 使用 - 基于 SLO 告警(Part 4):开源项目 pyrra 使用 - 基于 SLO 告警(Part 5):SLO 多租户与服务化 ---- 更多文章,请关注我们公众号 [【Grafana 爱好者】](https://mp.weixin.qq.com/s/tbyX7-3qGcHUDj5Igv5clQ)。

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2213 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传