🦮

Datadog SLO metricsベースとtime sliceの比較

に公開

こんにちは、TOKIUMでembedded SREをしております對馬です。
現在構築中の新規サービスにSLOを導入するにあたり、metricsベースSLOtime slice SLOの比較検討をしたところ、非常に興味深く、学びが深かったので記事にします。

概ねはDatadogの公式ページに書いてありますが、この記事では特に注意が必要と思われる、以下について深掘りします。

  • 時間ベースとカウントベースの違い
  • メトリクスにグループをしかけた時の挙動

この記事が誰かの助けになれば幸いです。

想定読者

  • SLOを概要レベルで知っている方
  • Datadog SLOの導入を考えておられる方

測定対象の違い

Datadogに比較ページがあるので、まずはこちらを確認します。
https://docs.datadoghq.com/ja/service_management/service_level_objectives/guide/slo_types_comparison/

  • メトリクス ベースの SLO: SLI の計算をカウント ベースにしたい場合に使用できます。SLI は、良いイベントの合計を全イベントの合計で割って算出します。
  • タイム スライス SLO: SLI の計算を時間ベースにしたい場合に使用できます。SLI はカスタムのアップタイム定義 (システムが良好な挙動を示した時間の合計を、総時間で割ったもの) に基づきます。タイム スライス SLO は Datadog Monitor を必要としません。SLO の作成中に各種メトリクス フィルターやしきい値を試し、ダウンタイムを即座に調査できます。

メトリクスベースはカウントベース、time sliceは時間ベースとなっており、ここが大きな違いです

  • time slice → 時間スライス(例: 1分単位)ごとの成功/失敗判定
  • metricsベース → イベント(リクエストや処理)ごとの成功率

カウントベースと時間ベースは、Datadog固有のものではなく、一般的なSLOの考え方として存在します。
(カウントベースはイベントベースと呼ばれてたりもしますが)
両者はベースが異なるため、同じ事象を計測したとしても、基本的に違う結果になります。(詳細は後述)

では、カウントベースと時間ベースでどう違うのか。
Alex Ewerlöfという方の記事がわかりやすかったので、引用をさせていただきます。
https://blog.alexewerlof.com/p/time-based-vs-event-based

time slice は時間が測定指標

time slice(time based) SLOでは、時間をスライスという単位で区切り、評価期間にどれだけ稼動していたかを基に計算を行います。

上記図の下側のバーがスライスと呼ばれる計算の単位になります。
time slice SLOではこれを使って、特定の評価期間のうちにどれだけ稼動状態OKなスライス(goodスライス)が存在するかをもってSLIを算出することになります。

計算例

項目 備考
1スライス 1分
評価期間 30日(43,200分) 30日 × 24時間 × 60分
good スライス 42,000
SLO 99.5%

上記の場合、SLIは以下のように算出されます

{SLI} = \frac{42000}{43200} \times 100\% = 97.2\%

SLOは99.5%と設定されているため、この場合はSLO違反となってしまいます

稼動判定の閾値

goodスライスかbadスライスかの判定のために、time slice SLOでは、稼動判定の閾値が必要になります。
例えば、リクエスト成功率の閾値99.5%以上と置いている場合は、1スライスごとに以下の判定が行われることになります。

\text{if} \quad \text{success\_rate}_{slice} >= 0.995

稼動判定の集計方法は、割合以外にも、平均値をとったり最小値をとったり色々あるよーとAlexさんは言っています。
Datadogでも、time sliceではSLIに全てのメトリクスタイプを利用できるため、いい感じの閾値が実現可能です。

メトリクスごとの利用できる集計方法は、以下に詳細が書かれています。
https://docs.datadoghq.com/ja/metrics/types/?tab=count

Datadogの主な設定値

time sliceの主な設定値は以下になります

  • 計測メトリクス
  • 閾値
  • 評価期間(7日 or 30日 or 90日)
  • time slice(1分 or 5分)
  • target(SLO)

後述するmetricsベースとの大きな違いは、閾値判定の設定があることです。
ここは、複数のメトリクスを選択したり、計算式を組んだりできるので、自由度が高いです。

運用上のポイント

time sliceを利用する場合にポイントになりそうな点をみていきます。

見通しはつけやすい

1スライスを1分、評価期間を30日とすれば、評価時期が1月だろうが2月だろうがtotal sliceは43200になります。
この特徴から、許容されるダウンタイムが何スライスなのかを最初から見通すことができます。

リクエスト数に影響されない

time sliceでは、1 slice中にどれだけエラー率がどれだけ高かろうが、1 bad sliceとして計上されます。
そのため、許容されるダウンタイムが60分だった場合、完璧なシステムダウンが30分起こっていたとしても、SLO上はOKという判断になってしまいます。

つまり、短期間の深刻な影響を見過ごしてしまう懸念があります

この点は、time slice SLOを採用するにあたって特に注意すべき点かと思います。

metrics(event)ベース はイベントが測定指標

対するmetrics(event) SLOでは、評価期間中のイベント総数と、goodイベントの数からSLIを算出します。

metricsベースは、イベント数が直でSLOに影響を及ぼします。
(※イベント:APIリクエスト発行回数などの指標にしているデータの発生回数)

time sliceで1 sliceという小さい範囲で稼動判定を行っていたのが、評価期間全ての範囲にわたって行われるイメージです。

計算例

項目
totalイベント数 10,000
good イベント数 9,000
SLO 99.5%

上記の場合、SLIは以下のように算出されます

{SLI} = \frac{9000}{10000} \times 100\% = 90.0\%

SLOは99.5%と設定されているため、この場合SLO違反となります

Datadogの主な設定値

metricsベースの主な設定値は以下になります

  • 計測メトリクス
    • good
    • total
  • 評価期間(7日 or 30日 or 90日)
  • target(SLO)

SLIはgood event / total eventから算出することになります。
閾値設定の項目がないぶん、設定値はtime sliceより少なくなります。

運用上のポイント

metricsもポイントになりそうな点をみていきましょう。

見通しはつけにくい

当然といえば当然ですが、metricsベースでは、最初の段階ではtotal イベントがいくつになるかはわかりません
time sliceでは、許容ダウンタイムに余裕があれば(長期にわたるインシデントが起こらない限りは)安心ができますが、metricsベースでは、短期間のエラー頻発によってエラーバジェットを消費しつくす可能性があります。

深刻な事象があれば、短期間でも捕捉できる

見通しのつけにくさの裏返しですが、metricsベースでは発生時間に関わらず、エラー発生回数がSLIに影響します
このため、影響度を補足しやすいのがmetricsベースの特徴です。

グループを使った時の挙動の違い

(ここからはDatadog固有の仕様の話になります)

グループとは、 メトリクスに付与されているタグに基づいて、データをグループに分けることができる機能のことです。
例えば、sum:xxx_service.api.count{*} by {api}.as_count()というクエリを使う場合、by {} で囲まれているapiがグループの単位になります。

apiというタグでグループを利用している場合、以下のように表示されます。

一番上のAll groupsが全体のSLOを表しています。

一つのSLOの中で、複数種類のデータ使いたい時に便利なんですが、グルーピング時の挙動にも違いがあるので、注意が必要です。

time sliceはグループ個別の成功率がSLIに影響する

time sliceでのグループの扱いは、以下のページに詳細が載っています。
https://docs.datadoghq.com/ja/service_management/service_level_objectives/time_slice/#グループと全体の稼働率

すべてのグループが稼働状態である場合にのみ、それを全体の稼働と見なし、いずれかのグループがダウンタイムの場合は全体をダウンタイムと見なします。そのため、全体の稼働率は常に各グループの稼働率より低くなります。

API-1、2、3という3つがグループの中にある場合、全てが合格状態である時のみ、good time sliceとして扱われることになります。

上記は特定のAPIのみ100%を下回っている時のtime slice SLOです。
一番上のAPIの影響で、bad time sliceとなった時間があったため、All Groupsにそれが影響しています。

1つのAPIの失敗率がクリティカルになりかねないので、SLIに使うデータは慎重に選んだ方が良いかもしれませんね。

metricsベースでは、グループ個別の成功率はSLIに影響しない

metricsベースでは対照的に、グループ個別の成功率はSLIに影響を及ぼしません。全体のgood / totalのみでSLIが算出されます

そのため、API-1、2、3という3つがグループの中にある場合、どれかひとつの成功率が著しく低かったとしても、リクエスト数自体が全体と比較して少なかった場合、SLOとしては問題なしとなってしまいます。

上記は、time sliceとほぼ同じ時間、同じ監視設定の、metricsベースSLOです。
All Groupsの99.70%という数値は、右側のGood Events(336)と、Total Events(337)から算出されており、グループ個別の成功率に関係なく、全ての合算値からSLIが算出されていることが見て取れます。

実行回数は少ないが、失敗がクリティカルな指標の影響が丸め込まれてしまうので、個別の品質が重要な場合は、グループは使わず、それぞれにSLOの設定を作った方が良いです。

アラートの仕様も異なる

上記のグループに対するスタンスの違いにあわせて、アラートの仕様も異なっています

グループを使ったmetricsベースのSLOにアラートを設定したい場合、SLOアラートではない形で設定する必要がありそうです。
(そういう形をとるなら、やはりグループは使わず個別にSLOを作った方がいいかもですが)

どっちを選べばいいんですか

Datadogの見解としては、メトリクスベースを選択することを推奨しています

  • 可能な限りメトリクス ベースの SLO を使用してください。SLO を違反するまでに残された不良イベント数をエラー バジェットが正確に反映するようにすることがベスト プラクティスです。SLO の計算は、イベント数に基づいてボリューム加重にもなります。

運用上のポイントで書いた、「深刻な事象があれば、短期間でも捕捉できる」点をベストプラクティスとして捉えているようです。

とはいえ、運用に乗らないSLOはその価値を失うので、自分の組織のニーズにあわせたSLOを導入することが一番大事なのではないかと思います。

TOKIUMプロダクトチーム テックブログ

Discussion