監視の仕組みを整えたあとに待っているのが、通知の多さという悩みです。
鳴りすぎれば誰も見なくなり、絞りすぎれば障害の第一報がユーザーから届くという板挟みになります。
どのアラートを残し、どれなら朝まで待たせてよいのか、線の引き方に迷ったことはありませんか?
答えの骨組みは、何を・いつ・誰に鳴らすかを別々に決めることにあります。
私も SRE は学んでいる途中なので、Google の SRE 本と SRE ワークブック、Prometheus と PagerDuty の公開ドキュメントを突き合わせて読みました。
アラートの行き先は三つしかない
Google の SRE 本の冒頭の章は、監視が出してよい出力を三種類に限っています。
一つ目のアラートは、人が今すぐ動く必要があるものです。
二つ目のチケットは、人の対応が要るものの、数日以内に手を打てば害が出ない事象を指します。
三つ目のログは、誰も見なくてよく、診断のために記録だけしておく情報です。
線を引く基準は、人の時間をどれだけ急いで奪ってよいかという一点に尽きます。
PagerDuty の Alerting Principles も、人の操作が要るものだけをアラートと呼び、それ以外を通知として分けています。
真夜中に人を起こすものは、すぐに人が対処できるものでなければならないとも明記しています。
重要度も、24 時間呼ぶもの、営業時間内だけ呼ぶもの、いつか対応すればよいもの、対応不要の通知の四段階でした。
何を鳴らすかは、原因ではなく症状で決める
SRE 本の Monitoring Distributed Systems の章は、監視が答える問いを「何が壊れたか」と「なぜか」に分けています。
前者が症状で、後者が原因です。
Prometheus のベストプラクティスは、アラートはできるだけ少なくし、ユーザーの痛みにつながる症状で鳴らすよう勧めています。
痛みの原因を一つ残らず捕まえにいくより、痛みそのものを見張るほうが通知は少なく済むという発想です。
Web サービスなら、レイテンシとエラー率をスタックのできるだけ上の層で見るよう書かれていました。
CPU 使用率のような原因側の指標は、ダッシュボードで追う側に回すのが自然です。
新しいアラートを足す前には、SRE 本が挙げている問いがそのまま判定に使えます。
- ほかの手段では気づけず、緊急で対処でき、ユーザーに見えている(見えかけている)状態か
- 無害だと分かっていて無視する場面がありそうか
- ユーザーが悪影響を受けていると確実に言えるか
- 通知を受けて何か手を打てるか
- 同じ件でほかの誰かも呼ばれていないか
答えに詰まるなら、チケットやダッシュボードに下げる候補と考えてよさそうです。
いつ鳴らすかは、エラーバジェットの減る速さで決める
次は、どの水準で鳴らすかという閾値の問題です。
SRE ワークブックの Alerting on SLOs は、アラートの良し悪しを適合率・再現率・検知時間・リセット時間の四つで測っています。
「10 分間の誤り率が許容値を超えたら鳴らす」という素朴な方式の弱点も、同書は示していました。
1 日に最大 144 回鳴り、そのどれにも対応しなくても SLO は守れてしまうという指摘です。
かといって「一定時間続いたら鳴らす」条件を足しても、値が一瞬でも戻るとタイマーがやり直しになり、検知が遅れます。
そこで同書が最終形として示すのが、バジェットを消費する速さ(バーンレート)を複数の時間窓で見る方式でした。
バジェットとバーンレートの考え方は、こちらにまとめました。
推奨値は、30 日分のバジェットの 2% を 1 時間で溶かす速さ(バーンレート 14.4)なら呼び出す、といった組み合わせです。
肝心なのは、長い窓に短い窓を「かつ」で重ねるところです。
長い窓だけだと、障害が収まったあとも平均が下がりきるまで鳴り続けてしまいます。
短い窓(目安は長い窓の 12 分の 1)を重ねれば、いま燃えているときだけ鳴り、止まれば数分で静かになるわけです。
同書の式を Prometheus のアラートルールに当てはめると、例えば次のようなイメージになります。
# SLO 99.9% を想定。誤り率は記録ルールで計算済みの前提
# 6h/30m(倍率 6)の組みも or でつなぐ(省略)
- alert: ErrorBudgetFastBurn
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)
labels:
severity: page
annotations:
summary: エラーバジェットが速いペースで減っています
# 手順書へのリンクなどもここに添える(略)
届け先を振り分け、通知をまとめ、手がかりを添える
「誰に」の出発点は、上の例の severity のようなラベルで届け先を分けておくことです。
そのうえで、大きな障害ほど関連するアラートが一斉に鳴り出す点への備えも必要です。
Alertmanager のドキュメントは、ネットワーク分断で数百の通知が出る例を挙げ、同種のアラートを一つの通知にまとめるグルーピングを説明しています。
クラスタごと到達できないと分かっている間は、関連する他の通知を止める抑制(inhibition)も用意されています。
手動で一時的に黙らせるサイレンスと合わせて、一つの障害で何度も人を起こさないための仕組みと言えます。
届いた通知には、次の一手を選ぶ手がかりも添えておくとよいでしょう。
アラートルールの annotations は、説明文や手順書(ランブック)へのリンクを置く場所として公式ドキュメントに書かれています。
疲弊を生む落とし穴
通知は、運用するうちに少しずつ増えていきます。
一つ目の落とし穴は、毎回同じ手順で片づく通知を呼び出しのまま残すことです。
SRE 本は、機械的な対応で済むものは呼び出しにすべきでないと書いていました。
そうした作業はトイルとして測り、自動化に回す候補になります。
トイルの測り方と減らし方は、別の記事にまとめました。
二つ目は、ほとんど鳴らないルールを放置することです。
SRE 本は、チームによっては四半期に一度も使われない設定を削除候補にする、という目安も挙げています。
鳴らないアラートは安心材料のようでいて、実は棚卸しの対象です。
三つ目は、アクセスの少ないサービスに同じ式をそのまま当てはめることです。
ワークブックは、1 時間に 10 リクエストのサービスでは、1 件の失敗で誤り率が 10% に跳ね上がると注意しています。
対策には、人工的なトラフィックを流す手などが挙げられていました。
数を減らすこと自体より、鳴ったら必ず誰かが動ける状態を保つことが目的だと考えると、判断がぶれにくくなります。
最後に
アラート設計は、何を・いつ・誰に鳴らすかを分けて決める作業でした。
- 何を … 原因ではなく、ユーザーに見える症状で呼ぶ
- いつ … エラーバジェットの減る速さを、長短二つの窓で見る
- 誰に … 重要度で届け先を分け、まとめて送り、手がかりを添える
そして、鳴ったら必ず誰かが動ける状態を、棚卸しで保ち続けることまでが含まれます。
まずは今あるアラートを三つの行き先に振り分け直すところから手をつけたいと考えています。
以上です。










コメントを残す