# イベントベース SLO ## 定義 SLO の集計方式には大きく 2 種類ある。**時間スライス(Time Slice)方式**は一定時間区間ごとに「良い区間か悪い区間か」を二値判定し、良い区間の割合を SLI とする。**イベントベース(Event-based)方式**は個々のリクエスト(イベント)を単位として「全リクエストのうち良いリクエストの割合」を SLI とする。 $SLI_{event} = \frac{Good\ Events_{TW}}{Total\ Events_{TW}} \times 100$ $SLI_{time\_slice} = \frac{Good\ Minutes}{Total\ Minutes} \times 100$ ### 時間スライス方式の問題:すべての分は等価でない 時間スライス方式は「分」を票として扱う。ピーク時(例: 1 分間に 1,000 リクエスト)も深夜(例: 1 分間に 10 リクエスト)も 1 票として扱うため、ユーザー影響の大きさが反映されない。(Source: [[@2023__SREcon23Americas__Not-All-Minutes-Are-Equal]]) **具体例**(p.10): 99.95 SLO、95% 閾値設定の場合、以下 6 分のデータを考える。 | 分 | Good | Total | SLI | 判定 | |---|---|---|---|---| | 1 | 98 | 100 | 98% | 良 | | 2 | 90 | 100 | 90% | 良 | | 3 | 1 | 100 | 1% | **悪** | | 4 | 9 | 10 | 90% | 良 | | 5 | 95 | 100 | 95% | 良 | | 6 | 98 | 100 | 98% | 良 | SLI_time_slice = 4/6 = **66%**(SLO 違反)。ただし Minute 3 の 99 件の悪いリクエストは「5% のエラーがエラーバジェットに届かない」閾値の外側に吸収されてしまう場合がある。反対に、Minute 4 では Total:10 と少量のトラフィックで 90% の SLI がエラーバジェットに大きく響く場合がある。 ### イベントベース方式の優位性 同じデータをイベントベースで集計すると、ピーク時の大量エラーがリクエスト数比で正確に反映される。結果として **EBR(エラーバジェット残高)の変動がインシデントの深刻度と比例**する。Capital One の実例(p.19)では "Badder Incident" で 18.1%↓、"Baddest Incident" で 36.6%↓ となり、障害規模との相関が視認できた。 時間スライス方式で同じデータを見ると "Badder Incident 0%↓"・"Baddest Incident 400%↓" という逆転現象が生じた(p.15)。 Capital One チームはこの 2 つのグラフに固有の呼称を与えている(口頭説明): - **"L グラフ"**: 時間スライス EBR のグラフ。急落後に横ばいとなる L 字形が特徴で、インシデントの深刻度差がほとんど反映されない。 - **"money chart"(お金になるグラフ)**: イベントベース EBR のグラフ。インシデントとの相関が分かりやすく、SLO の価値を経営層・ステークホルダーに説明する際の「売り物」になる。 ### 数式(付録) 時間窓 TW における完全な計算式(Source: [[@2023__SREcon23Americas__Not-All-Minutes-Are-Equal]] p.38): $SLI_{TW} = \frac{Good\ Events_{TW}}{Total\ Events_{TW}} \times 100$ $EB\ Max_{TW} = (1 - Objective) \times Total\ Events_{TW}$ $EB\ Current_{TW} = EB\ Max - Bad\ Events_{TW}$ $\%EB\ Remaining\ (EBR\%) = \frac{EB_{Current-TW}}{EB_{Max-TW}} \times 100$ 目標 %EBR から Objective を逆算するデフォルト SLO 式(「何 % にすればいいか分からない」チーム向け): $SLO_{default} = \left(\frac{bad}{(EB\%-1) \times Total} + 1\right) \times 100$ ## 横断的知見 - **時間スライスはトラフィックが平坦なシステムでは問題が出にくい**: バースト性の低いシステムでは両方式の差は小さい。問題が顕在化するのはトラフィックが周期的・季節的に大きく変動するシステムや、ピーク時に集中的に障害が起きるシステムである。 - **イベントベース集計はサンプリングと相性が良い**: トラフィックが多く全リクエストを計測しにくい場合、一定割合のサンプルからイベントベース SLI を算出できる。時間スライスでサンプリングすると分単位の判定精度が下がりやすい。 - **非同期パイプラインではイベントの「最終状態」のみを Valid Events として扱うことが重要**: eBay の実装(SREcon25 Americas)では、非同期イベントは SUCCESS・ABANDONED・RETRY の 3 状態を取るが、RETRY は過渡状態であり Valid Events から除外する。Valid Events = SUCCESS | ABANDONED のみ。これにより、再試行中のイベントが SLI を二重カウントする問題を回避できる。Capital One のイベントベース SLO における「リトライの二重カウント問題」(上記未解決の問い)の実践的な回答として機能する。(Source: [[@2025__SREcon25Americas__Beyond Sequential - A Recipe for Async Pipeline Observability and Alerting]], [[@2023__SREcon23Americas__Not-All-Minutes-Are-Equal]]) - **非同期パイプラインのレイテンシ SLI は HTTP の応答時間とは異なり「累積ホップ時間」で定義される**: eBay の実装では Producer → Queue 待ち → Consumer 処理 → Retry Queue 待ち → 再処理の全時間を Prometheus histogram に累積し、end-to-end レイテンシ SLI とした(合計 60ms の例: 10+10+10+30ms)。HTTP サービスの `response_time` と異なり、非同期では複数ホップにまたがる時刻スタンプ差分を記録する計装設計が必要になる。(Source: [[@2025__SREcon25Americas__Beyond Sequential - A Recipe for Async Pipeline Observability and Alerting]]) ## 未解決の問い - 時間スライス方式が採用されてきた歴史的経緯は何か(計装コストの問題か、Prometheus の recording rule の影響か)。 - ~~イベントベース方式ではリトライが二重カウントされる問題をどう扱うか~~ → **解決済み**: 非同期パイプラインでは RETRY を Valid Events から除外し、最終状態 SUCCESS | ABANDONED のみを集計対象とする(eBay 実装 / SREcon25 Americas)。 - Polling Period(最細粒度の集計区間)と Sampling Window(Burn Rate 計算用の区間)の設計ガイドライン(p.37)の実践的な選び方。transcript によると Capital One チームも「時間の単位について長時間議論した」と述べており、定番ガイドラインはまだ確立していないと思われる。 - 非同期パイプラインで Prometheus histogram の `le` ラベルをレイテンシ SLI に使う際、バケット境界の設計(10000ms, +Inf 以外のバケット粒度)はどう決めるか。 ## 関連 - 概念: [[サービスレベル目標]] / [[エラーバジェット]] / [[SLI-SLO段階的導入]] - ソース: [[@2023__SREcon23Americas__Not-All-Minutes-Are-Equal]] - 人物: [[Michael Goins]] / [[Troy Koss]] - 組織: [[Capital One]]