日々のこと

まいにちの暮らしをつれづれ書きます

サイトリライアビリティワークブックの読書メモ(1章、2章)

SREと名がつくチームで仕事することになったのですが、SREについて理解が浅いのと経験が薄いため、サイトリライアビリティワークブックを読んで、自分なりの読書メモを残そうと思います。

www.oreilly.co.jp

1章 SREとDevOpsの関係

DevOps

  • DevOpsは、IT開発、運用、ネットワーキング、セキュリティのサイロを壊すために設計されたプラクティス、ガイドライン、文化の緩やかな集合
    • CALMS(Culture / Automation / Lean / Measurement / Sharing )は、DevOpsの哲学を表す頭文字

SRE

  • SREは、仕事のロール、一連のプラクティス、プラクティスを活気付ける信念
    • DevOpsが掲げる哲学の一部を実施したもの
    • class SRE implements interface DevOps
    • 運用をうまく行うのはソフトウェアの問題 -プロダクトチームとSREチームは、適切な可用性のターゲットを選択し、サービスをSLOに応じて管理する
    • 手作業で強制される運用タスク(トイル)の最小化のための作業
    • Googleではトイルに費やすことができる時間に50%という上限を設けている

比較と対照

  • 計測は、DevOpsとSREの作業において絶対的な鍵、データ指向

組織のコンテキストと成功する採用の促進

  • 非難のないポストモーテム
  • DevOpsとSREどちらにとっても、開発速度の改善が成果であるべき
  • DevOpsとSREは、どちらも、確実に前進するための議論、経営層からの支援、実際に作業を行う人々からの同意を必要とする
  • DevOpsもSREも、プロダクションとその改善に向き合っている

2章 SLOの実装

  • サービスレベル目標(Service Level Objective = SLO)は、サービスの信頼性の目標レベルを示すもの
    • SLOは、信頼性に関してデータ駆動型の意思決定を下す上で鍵となるもの、SREの実践の中核

SREにSLOが必要な理由

  • SREの日々のタスクやプロジェクトは、SLOによって駆動される
    • SLOは、どのエンジニアリング作業を優先するかの決定を助けるツール

始めてみよう

  • サイトリライアビリティエンジニアリングにエラーバジェットベースのアプローチを採用するには、以下が成り立つ必要がある
    • SLOがあり、それがプロダクトに適していると組織内のすべてのステークホルダーが承認している
    • サービスがSLOを満たしていることを保証する責任を負う人々が、通常の状況下でこのSLOを満たせると同意した
    • 意思決定と優先順位付けにエラーバジェットを利用することに組織がコミットした
    • SLOを改訂するためのプロセスが存在する
  • 適切なSLOを形成するための最初のステップは、SLOが何であるべきか、SLOが何をカバーすべきなのか話し合うこと
    • サービスにおいて顧客のための信頼性のターゲットレベルを設定する
    • ユーザーの満足度が問題
    • 顧客を満足している状態に保つために、サービスの信頼性を保つ
    • 100%の信頼性は間違った目標
    • SLOをターゲットにしたら、機能リリースの速度と信頼性とのトレードオフを決める権限を持っている組織内の人物に、SLOの責任者になってもらう
  • 何を計測するか: SLIの利用
    • サービスレベル指標(Service Level Indicator = SLI)は、提供しているサービスのレベルの指標
    • SLIを2つの数値の比とする、良いイベントの数をイベントの総数で割ることを推奨している
      • 成功したHTTPリクエスト数 / HTTPリクエストの総数(成功率)
      • 100ms以内で正常に完了したgRPCの呼び出し数 / gRPCリクエストの総数 etc
    • この形式のSLIは0%から100%の範囲になり直感的、エラーバジェットの概念に適合する(SLOはターゲットのパーセンテージ、エラーバジェットは100%からSLOをひいた値)
    • 最初にSLIの形式化をしようとするとき、SLIの仕様とSLIの実装に分割すると便利かもしれない
    • 単一のSLIの仕様に複数のSLI実装が存在し、品質やカバレッジ、コストといった面でそれぞれに長所や短所がある
      • SLIの仕様:ユーザーにとって重要であると考えられるサービスのアウトカムに対する評価、計測方法とは独立している
        • 例:100ms未満でロードされたホームページリクエストの比率
      • SLIの実装:SLIの仕様とその計測方法
        • 例:100ms未満でロードされたホームページリクエストの比率で、サーバーログのレイテンシー列で計測されたもの。この計測には、バックエンドへの到達に失敗したリクエストは含まれない。
        • 例:100ms未満でロードされたホームページリクエストの比率で、仮装マシン内で動作するブラウザー上からJavaScriptを実行するプローバーで計測される。
    • 重要な目標は、何を定義して計測し、改善していけるように、フィードバックループをセットアップすること
    • 他に情報がなく、イテレーションのための良いプロセスがあるなら、現在のパフォーマンスは良い出発点
    • 最初のSLOの作成には、サービスで重要な鍵となるSLIの仕様を決める必要がある
    • どのSLIから始めるか、シンプルに始めること
      • SLOを定義したいアプリケーションを1つ選択する
      • 「ユーザー」が誰なのかはっきりさせる(このユーザーが満足度を最適化していく対象になる)
      • ユーザーがシステムとやりとりする一般的な方法を考える
      • システムの高レベルのアーキテクチャ図を書く(主要なコンポーネント、リクエストのフロー、データフロー、重要な依存関係)
    • SLIを設定し始めるには、システムをいくつかのよくあるコンポーネントタイプに抽象化すること
      • リクエスト駆動:ユーザーが何らかの種類のイベントを作成し、レスポンスが返ることを期待するコンポーネント
      • パイプライン:レコードを入力として取り、それを変化させ、どこか別の場所に出力するシステム
      • ストレージ:データを受け取り、それを取り出せるようにしておくシステム

うまく行った例

  • 顧客にとって最も重要な機能を表現する、少数(5つ以下)のSLIを選択することを推奨
    • いくつかのSLIは、複数グレードのSLOを用いることをおすすめする
    • 90%のリクエストは100ms以下、99%のリクエストは400ms以下
  • 様々な種類のコンポーネントで利用可能なSLI

SLIの仕様からSLIの実装への移行

  • SLIの仕様が決まったら、SLIの実装を考え始める
  • 最初のSLIは、最もエンジニアリングの作業が少なくて済むものを選択する
  • SLIは具体的で計測可能でなければならない
  • API及びHTTPサーバーの可用性とレイテンシー
    • 可用性SLI:成功したリクエストの比率
    • レイテンシーSLI:定義された閾値よりも高速だったリクエストの比率
    • この例では、メトリクスがすでに利用でき、ユーザー体験に近いSLIを提供してくれることから、ロードバランサーのモニタリングを利用
  • パイプラインの新鮮さ、カバレッジ、正確性
    • パイプラインの新鮮さ:テーブルの全てのクライアントが、新しいデータをリクエストし、そのデータがリクエストされたことを示すメトリクスのカウンターをインクリメントする前に、ウォーターマークをチェックするようにする
      • データが事前に決められた閾値よりも新しいなら、別のカウンターもインクリメントする
    • カバレッジ:パイプラインは、処理すべきレコード数と、処理に成功したレコード数をエクスポートする
    • 正確性:ゲームの状態のデータベース内に、手作業で選別されたデータに対して、パイプラインを実行するたびにその出力が既知の正しい計算結果と一致するかに基づく
      • このSLIが実際のユーザー体験を表現するためには、手作業で選別するデータが実世界のデータの代表例となるようにしなければならない

SLIの計測

  • ロードバランサのメトリクス(Prometheusの表記を利用)
    • 一般的には、遅いリクエストは、ヒストグラムから概算するよりも直接カウントする方が良い
    • 今回は直接のカウントは利用できないので、モニタリングシステムが提供するヒストグラムを利用
    • もう1つのアプローチとして、ロードバランサーに低速の閾値をもうけ、明示的にカウントした低速なリクエスト数に基づくという方法がある
      • この方法は正確な数値が得られるが、設定が多く必要になり、過去に遡って閾値を変更するのが難しい
  • SLIの計算
    • 可用性:sum(rate(http_requests_total{host="api", status!~"5.."} [7d])) / sum(rate(http_requests_total{host="api"} [7d]))
    • レイテンシ
      • histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[7d]))
      • histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[7d]))

SLIを使った最初のSLOの計算

  • これらのSLIをまとめて、最初のSLOを得るために管理しやすい数値にできる
  • たとえば、ある4週間でAPIメトリクスが以下の数値だった
  • API向けに以下のSLOの提案を作成、これを基にエラーバジェットも計算可能

適切な時間ウィンドウの選択

  • SLOは様々な時間感覚に対して定義できる
  • ローリングウィンドウの選択は、いくつかの要素を考慮に入れる必要がある
  • ローリングウィンドウは、ユーザー体験に密接に沿っている
  • 期間をしゅうの整数倍を単位として定義し、常に同じ数の週末が含まれるようにすることを勧める
    • 30日のウィンドウを採用すると、4つの週末や5つの週末が含まれ、平日と週末のトラフィックが異なる場合、SLIが変更しかねない
  • カレンダーのウィンドウは、ビジネスの計画やプロジェクトの作業とより密接に沿っている
  • ウィンドウを短くすれば判断をより早く下せる
  • 期間を長く取れば、より戦略的な判断に役立つ
  • 4週間のローリングウィンドウが汎用的な機関として優れていることを見出した
    • このタイムフレームを、タスクの優先順位付けのための週間のサマリと、プロジェクトプランニングのための四半期の集計レポートで補足している
  • このSLOを案を使って、実際のSLOパフォーマンスをこの期間に対して計算してみることができる

ステークホルダーの同意を得る

  • SLOの案が有益で効果的なものであるためには、全てのステークホルダーが同意している必要がある
  • SLOを守るには、モニタリングとアラートをセットアップして、エラーバジェットに脅威が生じたときに、その危険が損失になる前にエンジニアがタイムリーに通知を受けられるようにしなければならない

エラーバジェットポリシーの確立

  • SLOができたら、SLOを使ってエラーバジェットを導き出せる
  • サービスがバジェットを使い果たしてしまったときに行うことを大まかに定めたポリシーが必要
  • プロダクトマネージャー、開発チーム、SREの3つのグループ全てがエラーバジェットポリシーを強制することに同意しないのであれば、全てのステークホルダーが満足するまでSLIとSLOの作業を繰り返す必要がある
  • エラーバジェットを使い果たしてしまったら、システムの安定性を回復するために何をすべきか
  • このポリシーは、エラーバジェットを使い果たしてしまった場合にとらなければいけないアクション、そのアクションを誰が行うのかをカバーしていなければならない

SLOとエラーバジェットポリシーのドキュメント化

  • 適切に定義されたSLOは、他のチームやステークホルダーがレビューできるような目立つ場所にドキュメント化されなければならない
  • SLOドキュメントのレビュー頻度は、SLO文化の成熟度に依存する
    • 初めはおそらく頻繁に、月ごとにレビューすべき
    • SLOの妥当性が確立されてきたら、四半期ごともしくはそれ以下に頻度を減らせる

ダッシュボードとレポート

  • サービスのSLOへの達成状況のリアルタイムのスナップショットを提供するレポートとダッシュボードがあると、他チームとのコミュニケーションや問題領域の特定に役立つ
    • サービスの全体的な準拠状況を示す
    • SLIのトレンドを示すのも役立つ

SLOターゲットの継続的改善

  • SLOターゲットを改善できるようになる前に、サービスに関するユーザーの満足度についての情報源が必要
  • 収集が安価に行える計測からはじめ、その出発点からイテレーションしていくことをお勧め
    • プロダクトマネージャーに対し、これまで行っている顧客との価格と機能についての議論の中に、信頼性を含めてもらうことを頼むことは良い出発点
  • 手作業で検出したサービス障害をカウントする
    • 既知のサービス障害またはインシデントがあるなら、その期間を見る
    • SLIが問題の存在を示しているときや、サービスがSLOから外れ落ちてしまっている期間を見る
  • サービス障害やチケットのスパイクで、SLIやSLOで補足されないものがある場合や、SLIの低下やSLOからの逸脱でユーザーに影響する問題にマッピングされないものがあるなら、SLOのカバレッジが不足していることを示唆している
  • SLIやSLOは、それらが表現しているサービスの実態が時間と共に変化するにつれて変わっていくべきもの
  • SLOのカバレッジが不足している場合に取れる措置
    • SLOの変更:SLIが問題を示しているものの、SLOは誰にも通知や反応を促していない場合、SLOを厳しくする必要があるかもしれない
    • SLIの実装の変更:1. メトリクスの質を改善するために計測をユーザーに近づける or 2. ユーザーのインタラクションのより広いパーセンテージを細くできるようにカバレッジを改善する
    • 野心的なSLOの制定:ユーザーを満足させるためにもっと厳しいSLOが必要だと判断したものの、そのSLOを満たせるようプロダクト改善するのは時間がかかるような場合、改良したSLOを野心的なSLOとするのが良い(エラーバジェットポリシー内では明示的にアクションが必要ないものとする)
    • イテレーション:投資に対するリターンが最も大きくなりそうな選択肢を選ぶ、特に最初の数回のイテレーションでは早くて楽すぎるくらいのやり方を選ぶ

SLOとエラーバジェットを使った意思決定

  • SLOができたら、それを意思決定に利用し始められる
  • 明らかな意思決定は、SLOが満たされていないとき、エラーバジェットを使い果たしたときに何を行うかから始まる
  • エラーバジェットポリシーでカバーされているべき
  • SLO、トイル、顧客満足度の3つの次元に基づいて、とるべきアクションが変わる
    • SLO:満、トイル:低、顧客満足度:高 -> リリースとデプロイメントのプロセスを緩和して速度を早める or エンゲージメントレベルを下げ、より信頼性を必要とするサービスにエンジニアリングの時間を集中させるか選択する etc

高度なトピック

  • 健全で成熟したSLOとエラーバジェットの文化ができたら、サービスの信頼性の計測と議論の方法を改善していくことができる

ユーザージャーニーのモデリング

  • 究極的にはSLOの主眼は、顧客体験の改善であるべき
  • SLOはユーザーを中心に置くアクションについて書かれるべき
  • 顧客の体験の補足するには、クリティカルユーザージャーニーが利用できる
    • あるユーザーの体験の中核部分となるタスクの並び
    • オンラインショッピングなら、商品の検索 -> ショッピングカートへの商品の追加 -> 購入の完了
  • ユーザー中心のイベントを計測できるようになれば、それはもう1つのSLIとなり、既存のSLIやSLOと共に追跡できる
  • クリティカルユーザージャーニーは、適合率(precision)に影響することなく再現率(recall)を改善できる

インタラクションの重要性の段階付け

  • すべてのリクエストが同等ではない
  • ある種類のリクエストを他の種類のリクエストから区別するには、バケット化が利用できる
    • SLIにラベルを追加し、それらのラベルに異なるSLOを適用する
    • 顧客の階層:プレミアム -> 99.99%、無料 -> 99.9% etc
    • 期待されるレスポンス性でリクエストを分割することもできる
    • インタラクティブ -> 90%が100ms以内に完了、CSVダウンロード -> 90%のダウンロードが5秒以内に開始 etc

依存関係のモデル化

  • 大規模なシステムには多くのコンポーネントがある
  • SLOは、スタック中の様々なコンポーネント間の信頼性と要求の調整と実装にも役立つ
    • ある単一のコンポーネントが、特に価値の高いインタラクションの必須な依存対象だった場合、その信頼性の保証は依存するアクションの信頼性の保証と同程度に高くあるべき
    • あるコンポーネントが元から信頼性に制限を持っているなら、SLOにその制限を盛り込める
  • 他のチームが扱っている依存対象が原因で生じた障害によって満たせなかったSLOにエラーバジェットがどう対処すればいいか
      1. 自分たちのシステムが問題を起こしたわけれはないので、チームはリリースの停止や信頼性のために時間を費やすことはしない
      1. 将来の障害の可能性を最小限にするために、変更の凍結を行うべき -> ユーザーをより幸福にする
  • サービスとその依存対象にとって最も適切な判断を下し、後のためにドキュメント化されたエラーバジェットにその判断を記録しておく

SLOを緩めてみる

  • アプリケーションの信頼性を実験し、信頼性におけるどのような変更がユーザーの振る舞いにはっきりと好ましくない影響を及ぼすか計測してみたい場合もある
  • 消費できるエラーバジェットがあることに確信が持てる場合に限る、用心深く行うべき
  • こうした実験で知識を得れば、将来さらに優れたパフォーマンスにつながる方法でサービスを改善できる

まとめ

  • 制定したSLOは、システムの振る舞いについて議論するためのフレームワークを提供し、サービスが期待を満たせなかった場合に行える改善策を正確に示す役に立つ
  • SLOは、サービスの信頼性を計測するツール
  • エラーバジェットは、信頼性と他のエンジニアリング作業とのバランスを取るためのツール、どのプロジェクトが最もインパクトがあるかを判断する素晴らしい方法
  • SLOとエラーバジェットは今日にも使い始めるべき