0

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

 1 year ago
source link: https://studygolang.com/articles/36037
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本篇文章为《基于 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 (30240.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 爱好者】


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK