写点什么

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

  • 2023-02-02
    江苏
  • 本文字数:2494 字

    阅读完需:约 8 分钟

本篇文章为《基于 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 种方案都采用固定时间窗口和固定阈值的方式,为了改进方案,我们很自然想到基于错误预算燃烧耗率的方法,针对不同燃烧率我们可以配置不同告警级别,消耗越快,告警级别越高。


燃烧率与耗尽时间的关系如表格:



那么我们该使用怎样的燃烧率呢?


举个例子,在 1 小时内燃烧了 30 天错误预算的 5%,这就需要触发告警了,此时可以得到燃烧率为 36 (30240.05/1)。


其告警规则为:


- alert: HighErrorRate  expr: job:slo_errors_per_request:ratio_rate1h{job="myjob"} > 36 * 0
复制代码


这种方法虽然解决前面提到的一些误报和恢复重置时间长的问题,但假如服务的燃烧率恰好只有 35,意味着 20.5 小时将消耗完所有的错误预算,而且您收不到任何告警。

方案 5:基于多个燃烧率

方案 4 中只有一个固定的消耗率,针对固定 35 燃烧率的问题,我们可以使用多个燃烧率来避免,不同燃烧率可以对应不同告警级别。


比较建议的时间窗口和燃烧率,消耗的 SLO 百分比对照表如下:



告警规则配置为:


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.001severity: ticket
复制代码


这种方式能够解决方案 4 中的问题,但同一现象可能会触发多条告警,这意味着您需要更智能的告警抑制手段。


例如,五分钟内消耗了 10%的预算,也意味着六小时内消耗了 5%的预算,一小时内消耗了 2%的预算,所以您可能会同时收到 3 条不同告警信息。

方案 6:多窗口、多燃烧率

我们继续在方案 5 之上进行迭代,思路很简单,确保当前服务仍在不断消耗预算的时候才进行告警。


为此我们需要增加一个短时间观察窗口,一般短窗口的时间为长窗口的时间的 1/12,只有两个时间窗口燃烧率都满足条件,才进行告警通知。


99.9% SLO 警报配置的推荐参数表为:



所以最后告警规则配置大致为:



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 爱好者】

发布于: 2023-02-02阅读数: 22
用户头像

学习是从了解到使用再到输出的过程。 2018-04-27 加入

GrafanaFans 是由南京多位 Grafana 爱好者一起发起的 Grafana 开源产品学习小组,致力于 LGTM(Loki、Grafana、Tempo、Mimir)技术栈在国内的普及和应用,欢迎关注开源项目 https://github.com/grafanafans/club。

评论

发布
暂无评论
基于SLO告警(Part 2):为什么使用MWMB方法_可观测性_Grafana 爱好者_InfoQ写作社区