Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

This post is Private. Only a writer or those who know its URL can access this post.

posted at

updated at

SRE WorkBook Chapter5 Alerting on SLOs p75 ~ 85

今回のまとめ(Chapter5 Alerting on SLOs p75 ~ 85)

  • アラート戦略は、精度・リコール・検出時間・リセット時間で考えよう
  • SLOに対するアラートのやり方としては 「複数のバーンレート・複数のウィンドウでアラートを設定する」やり方がベスト!

以下原文の訳(Chapter5 Alerting on SLOs p75 ~ 85)

※原文(英語)を参照したい場合は、マークダウンのコメントに書いてあります。この記事のURLに .md をつけてアクセスしてください。

この章では、SLOを、重要なイベントに対してアクションを起こせるようなアラートへと落とし込む方法について説明します。
最初のSRE本でも、本書でも、SLOの実装について説明しています。
信頼性を測る良いSLOは、オンコールエンジニアがどんな時に対応すべきなのかについて、非常に高品質な指標となります。
この章では、SLOを、エラー・バジェットを過度に消費する前に問題に応答できるようなアラーティングルールに変える方法について、具体的なガイダンスを示します。

この章の例では、アラートに使うメトリクス・アラーティングロジックについて、徐々に複雑にしながら実装方法を紹介していきます。
それぞれの有用性と欠点について議論して行きましょう。
この章の例では、単純なリクエストドリブンなサービスとPrometheusの構文を使用しています。しかし、このアプローチはどのアラーティングフレームワークにも適用できます。

アラートにおいて考えるべきこと(Alerting Considerations)

サービスレベル指標(SLI)とエラーバジェットからアラートを生成するには、これらの2つの要素を組み合わせて、特定のルールにする必要があります。
重要なイベント、すなわちエラーバジェットの大部分を消費するイベントについて、通知されるようにする必要があります。

アラート戦略を評価する際、以下のような属性を考えましょう。

  • 精度(Precision)
    • 検出されたイベントについて、それが重要である割合。
    • すべてのアラートが重大なイベントに対応する場合、精度は100%です。
    • アラートは、低トラフィック期間中の重要でないイベントに特に敏感になる可能性があることに注意してください(「低トラフィックサービスとエラーバジェットアラート」(86ページ)を参照)。
  • リコール(Recall)
    • 重要なイベントが検出される割合(重要なイベントが人の召喚(recall)に繋がる割合)
    • すべての重要なイベントの結果がアラートになると、リコールは100%になります。
  • 検出時間(Detection time)
    • 様々な状況における、通知が送信されるまでの時間。
    • 検出時間が長いと、エラーバジェットへのダメージが大きくなりやすくなります。
  • リセット時間(Reset time)
    • 問題が解決された後にアラートが発生し続ける時間。
    • リセット時間が長いと、混乱・問題の見過ごしに繋がります。

重要なイベントに対して、アラートする手法(Ways to Alert on Significant Events)

SLOに対するアラートの構築は、非常に複雑になることがあります。
ここでは、忠実度を高めるために、重要なイベントに対してアラートを設定する6つの手法を紹介します。そして、精度、リコール、検出時間、およびリセット時間の4つのパラメータについて、同時に上手にコントロールできるやり方に到達します。

以降の各アプローチは異なる問題に対処し、いくつかのアプローチは最終的に同時に複数の問題を解決します。
最初の3回の実行不可能な試みは、3つ目の実行可能なアラート戦略に向けて進めています。
アプローチ6は、最も実行可能で最も推奨されるオプションです。アプローチ1は実装が簡単ですが不十分なものです。アプローチ6は長期的および短期的にSLOを防御する完全なソリューションを提供します。

この議論の目的上、「エラーバジェット」と「エラー率」は、すべてのSLIに適用されます(「エラー」と言う名前を冠していない指標も含みます)。
良いイベントの量とイベントの合計量の比率をキャプチャするようなSLIを使うことをお勧めします。(20ページ: What to Measure: Using SLIs を参照)
エラーバジェットは、許容されるエラーイベントの数です。エラー率は、エラーイベントの合計イベントに対する比率です。

1: エラー率 >= SLOの閾値(Target Error Rate ≥ SLO Threshold)

最も単純な解決策は、小さな時間ウィンドウ(たとえば10分)を設定し、そのウィンドウにおけるエラー率がSLOを超えたらアラートするものです。
たとえば、SLOが「30日間で99.9%」の場合、直近の10分間のエラー率が0.1%以上であればアラートを発報します。

// Prometheus Alerting Rules
- alert: HighErrorRate
  expr: job:slo_errors_per_request:ratio_rate10m{job="myjob"} >= 0.001
// Prometheus Recording Rules
record: job:slo_errors_per_request:ratio_rate10m
expr:
  sum(rate(slo_errors[10m])) by (job)
  /
  sum(rate(slo_requests[10m])) by (job)

// If you don’t export slo_errors and slo_requests from your job,you can create the time series by renaming a metric:
// record: slo_errors
// expr: http_errors

直近のエラー率に対するアラートがあった場合、以下の計算式のバジェットが消費されたことを意味します
(アラートウィンドウの大きさ) / 期間

図5-1

図5-1は、10分間のアラートウィンドウと99.9%のSLOを備えたサービスにおける、検出時間とエラー率の関係を示しています。

以下に「直近のエラー率が高すぎる場合にアラートする」アプローチの、長所・短所を示します。

長所 短所
検出時間が短い。完全なアウテージの場合は0.6秒で検出される。アラートは、SLOを脅かすあらゆるイベントで発生するため、リコール(Recall)は良い。 精度(Precision)が低い:SLOを脅かさない多くのイベントに対して、アラートが発生する。 10分間で0.1%エラー率となった時もアラートされるが、消費されるエラーバジェットは一ヶ月分の0.02%でしかない。
極端な例で言うと、1日あたり最大144件のアラートを受け取ることが、アラートには反応せずともSLOを達成できるケースも起こりうる。

2: アラートウィンドウを大きくしてみる(Increased Alert Window)

前述の例について、アラートウィンドウのサイズを変更することで精度を向上させることができます。
ウィンドウサイズを大きくすることで、より多くのエラーバジェットが消費された時にアラートされるようになります。

アラートの頻度を管理しやすくするために、「36時間ウィンドウの中で、30日間におけるエラーバジェットの5%が消費された時に通知が行われる」ようにします。

// Prometheus Alerting Rules
- alert: HighErrorRate
    expr: job:slo_errors_per_request:ratio_rate36h{job="myjob"} > 0.001

このようにした時、検出までの時間は以下のようになります:
(1 − SLO) × (アラートウィンドウの大きさ)

「大きなアラートウィンドウを設定し、その中でのエラー率が高すぎる場合に通知する」アプローチの長所・短所は以下の通りです。

長所 短所
検出時間がまだ十分に短い。完全停止の場合でも2分10秒。 リセット時間が非常に悪い:完全停止の場合、アラートは2分後に発火するが、その後36時間に渡り発火し続ける(その後何もエラーイベントが発生しない場合であっても)。
大きなウィンドウでエラー率計算を行うと、多数のデータポイントを扱うため、メモリまたはI/Oオペレーションの観点で高コストになりうる.

図5-2に示すように、エラー率は無視できるレベルに低下していますが、36時間の平均エラー率は閾値を超えたままです。(なので36時間アラートされ続ける)

図5-2

3: 長めの継続時間を設定してみる(Incrementing Alert Duration)

ほとんどの監視システムでは、アラート基準に継続時間パラメータを追加し、値がしばらく閾値を超えないとアラートされないようにすることができます。
より長いウィンドウを追加するために比較的安価な方法としてこのパラメータを使用するように誘惑されるかもしれません

// Prometheus Alerting Rules
- alert: HighErrorRate
    expr: job:slo_errors_per_request:ratio_rate1m{job="myjob"} > 0.001
    for: 1h

「継続時間を設定する」アプローチの長所・短所は以下の通りです。

長所 短所
アラートの精度がより高くなる。アラート前にエラー率が継続することを要求することで、アラートが重大な事象に対応する可能性がより高まる。 リコールが不十分 + 検出時間が長い:
インシデントの重大度によって必要な継続時間が変化しないため、完全停止の場合でも、アラートまで一時間を要する(0.2%停止の場合と同じ検出時間)。 一時間100%停止すると、30日間のエラーバジェットの140%を消費する。
メトリックがSLO内のレベルに戻ったのが一時的でしかない場合でも、継続時間タイマーはリセットされます。 SLIが、SLOを下回ったり上回ったりと変動し続ける場合、アラートは行われない

上記の理由から、継続時間をSLOベースのアラート基準に使用することは推奨されません。
図5-3は、アラート発生までの継続時間が10分の場合の、5分間のウィンドウにおける均エラー率を示しています。10分ごとに発生する、5分間持続する一連の100%エラースパイクは、エラーバジェットの35%を消費するにもかかわらず、アラートをトリガーしません。
一回のスパイクは30日間のエラーバジェットのほぼ12%を消費しますが、アラートは決して発生しません。

図5-3

4: バーンレートベースでアラートする(Alert on Burn Rate)

ここまでで述べたやり方をより良くするには、アラートの検出時間と精度をあげる必要があります。
バーンレート(燃焼率)を導入することで、エラーバジェットを一定に保ちながら、ウィンドウサイズを小さくできます。

バーンレートは、サービスがエラー・バジェットを消費する速度です。 図5-4に、バーンレートとエラーバジェットの関係を示します。

図5-4

この例における、バーンレートは1です。これは、SLOの期間ウィンドウの最後にエラーバジェットが0になる速度で、エラー・バジェットを消費することを意味します(最初のSRE本の第4章を参照)。 30日間において99.9%のSLOの場合、一貫した0.1%エラーレートはエラーバジェットのすべてをきっちり使い切った時にバーンレートは1になります。

以下にバーンレート・対応するエラー率・エラーバジェットを使い切るまでの時間の表を示します。

バーンレート 99.9% SLOの場合のエラー率 エラーバジェットを使い切るまでに要する時間
1 0.1% 30日
2 0.2% 15日
10 1% 3日
1000 100% 43分

アラートウィンドウを1時間とし、エラーバジェットが5%消費された時を通知すべき場合と定義すると、そこからアラートに使用すべきバーンレートを導出することができます。
バーンレートベースのアラートの場合、アラート発報までの時間は以下のようになります。

(1 - SLO) / (エラー率) * (アラートウィンドウの大きさ) * (バーンレート)

アラート発報までに消費されるエラーバジェットは以下のようになります。

(バーンレート) * (アラートウィンドウの大きさ) / (期間)

30日分のエラーバジェットのうちの5%を1時間で消費する場合、バーンレートは36です。
すると、アラートルールは以下のようになります。

// Prometheus Alerting Rules
- alert: HighErrorRate
  expr: job:slo_errors_per_request:ratio_rate1h{job="myjob"} > 36 * 0.001

「バーンレートベースのアラート」の長所・短所は以下の通りです。

長所 短所
良い精度:この戦略では、使われたエラーバジェットを元に重要な期間だけアラートする。
ウィンドウが小さいので計算は低コスト。
良い検出時間。
リセット時間も改善されている:58分
低リコール: バーンレート35の場合、アラートは発報されないが、20.5時間でエラーバジェットを使い切ってしまう。
リセット時間: 58分はまだ長すぎる。

複数のバーンレートを組み合わせる(Multiple Burn Rate Alerts)

アラートロジックでは、複数のバーンレートと時間ウィンドウを使用できます。そして、複数のバーンレートのどれかが閾値を超えた時に、アラートを発することができます。
このようにすることで、バーンレートベースでのアラートのメリットを損なうことで、低い(しかし重要な)エラーレートが見過ごされないようにすることができます。

例えば、3日で10%のエラーバジェットが消費されている場合など、アラートするほどでもないが、放置するとエラーバジェットを使い果たしてしまうような障害については、
チケット通知を設定するのが良いです。
3日で10%というエラー率は重要なイベントを捕捉できます。この消費率の場合、イベントに対処するのに十分時間を使えるため、ページする(検出次第、直ちにリコールする)ことはありません。

適切な数値は、サービスとベースラインページの負荷によって異なります。 より混雑したサービスや、週末や休日のオンコールの責任に応じて、6時間の窓口でのチケットアラートが必要な場合があります。

ページングの合理的な基準としては、1時間で2%のエラーバジェット消費、6時間で5%のエラーバジェット消費が推奨されます。
チケットアラートの合理的な基準としては、3日で10%の予エラーバジェット消費が推奨されます。

適切な数値は、サービスやページ負荷のベースラインによって異なります。
忙しかったり、週末や休日にオンコールの責任がなかったりする場合は、6時間ウィンドウのアラートをチケット対応とすることもできます。

表にすると以下のようになります。
| エラーバジェット消費量 | 時間ウィンドウ | バーンレート | 通知方法 |
| 2% | 1時間 | 14.4 | ページ |
| 5% | 6時間 | 6 | ページ |
| 10% | 3日 | 1 | チケット |

アラートルールは以下のようになります。

// Prometheus Alerting Rules
- alert: HighErrorRate
  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

図5.5は検出時間とエラー率に応じた通知方法を表しています。

図5.5

それぞれのバーンレートについて、求められる対応の迅速さに基づき、適切な優先度を与えるようにアラートを調整できます。
数時間または数日以内にエラー予算を使い果たすような問題の場合は、アクティブな通知(ページ)を送信するのが適切です。
そうでなければ、翌営業日にアラートに対処するチケットベースの通知の方が適切です。

「複数のバーンレートを組み合わせる」アプローチの長所・短所は以下の通りです。

長所 短所
多くの状況に対応し、緊急度に応じた監視ができる:エラー率が高い場合に迅速はすぐにアラートする。エラー率は低いが持続している場合には段階的にアラートできる。
精度が高い(期間内に一定のエラーバジェットが消費された場合...と同様の精度がある)
3日間のウィンドウのおかげで、リコールも良い
どの程度緊急で対応しないといけないかに応じて、適切な通知方法でアラートすることができる。
管理するメトリクス、ウィンドウサイズ、閾値のの数が多い。
さらに長いリセット時間(3日間のウィンドウ)
同じ事象が複数のアラートのルールに該当した時に、複数のアラートが発報しないようにするには、アラートが抑制されるような設定をする必要がある。
たとえば、5分で10%のエラーバジェットが消費されたケースにおいて、エラーバジェットの5%が6時間で消費されたという条件も、エラーバジェットの2%が1時間で費やされたという条件も満たします。このケースにおいて、監視システムが十分スマートでない限り、3つの通知を同時に発報してしまう。

6: 複数のバーンレート・複数のウィンドウでアラートを設定する(Multiwindow, Multi-Burn-Rate Alerts)

アプローチ5の、複数のバーンレートによるアラートを強化して、まだエラーバジェットが現在進行形で消費されている場合にのみ通知するように変更することで、偽陽性の通知を減らすことができます。
エラーバジェットが現在進行形で消費されているかを判定するためには、別のパラメータを追加する必要があります。
アラートをトリガするときにエラー予算がまだ消費されているかどうかを確認するための短いウィンドウです。

良い指針として、図5-6に示すように、短いウィンドウを長いウィンドウの持続時間の1/12にすることです。
グラフには両方のアラート閾値が示されています。
10分間15%のエラーが発生すると、

  1. 短いウィンドウの平均がすぐに警告の閾値を超えます。
  2. 5分後に長いウィンドウの平均が閾値を超え、その時点でアラートが開始されます。
  3. 短いウィンドウの平均値は、エラーが停止してから5分後に閾値を下回り、その時点でアラートは停止します。
  4. 長いウィンドウ平均は、エラーが停止してから60分後に閾値を下回ります。

図5-6

たとえば、直前の1時間と過去5分間の両方で14.4倍のバーンレートを超えると、ページレベルのアラートが送信されます。
このアラートは、エラーバジェットの2%を消費した後でのみ発生しますが、リセット時間5分でアラートを静かにさせることができます。(一時間かかることはありません)。

// Prometheus Alerting Rules
  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

SLOベースのアラートを始めるにあたって、初期設定の推奨値は以下の通りです。

重要度 長いウィンドウ 短いウィンドウ バーンレート 消費されたエラーバジェット
Page 1 hour 5 minutes 14.4 2%
Page 6 hour 30 minutes 6 5%
Ticket 3 days 6 hours 1 10%

SLOベースのアラートを行うにあたり、複数のバーンレートを使う手法が非常に効果的であることがお分りいただけたでしょうか。

「複数のバーンレート・複数のウィンドウでアラートを設定する」アプローチの長所・短所は以下の通りです。

長所 短所
インシデントの重大度と組織の要件に従ってアラートの種類を制御できる柔軟なアラートフレームワーク。
精度が高い(期間内に一定のエラーバジェットが消費された場合...と同様の精度がある)
3日間のウィンドウのおかげで、リコールも良い
指定するパラメータがたくさんあり、アラートルールを管理するのが難しい。
アラートルールの管理の詳細については、89ページの「スケールに応じたアラート」を参照してください。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
Help us understand the problem. What are the problem?