SREの実践、SLI/SLO策定までの道のり

この記事はエイチーム引越し侍/エイチームコネクトの社員による、[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hikkoshizamurai-connect) 8日目の記事です。

8日目は、エイチームグループ内でもレアキャラなインフラエンジニアの @sugoto911 が担当します。
趣味はカメラ、登山、キャンプです！ :camera_with_flash: :mountain: :camping:
今年も雪が多いようなので、これからの季節はスキーを楽しみたい所存です。
来世は長野県松本市在住の山ガール予定なので、生暖かい目で見守っていただけると嬉しいです:wink:

仕事では**「推測するな、計測せよ:chart_with_upwards_trend:」**をモットーに、日々インフラの管理や監視、Observabilityの整備を行っています。

## はじめに
私がSREという方法論に出会ったのは、まだエイチーム引越し侍に入社前の2018年頃です。
当時はそもそも「信頼性とはなんぞ・・・？」というレベル、日々の業務においても信頼性を意識することはなく、単に**システム障害は起こしてはいけないもの**と考えていたものです。

SRE自体や各プラクティスについても曖昧な理解のまま、2020年にエイチーム引越し侍へ入社、その直後に開催された **SRE NEXT 2020** に参加し、そこで見聞きしたものに大きな衝撃を受けたことが転換期となりました。

https://sre-next.dev/

得たものをすぐに持ち帰ったところ、上司も「SRE実践したいな〜」と言っていたため、やっていき！:fist:宣言をし、そこから長い旅路が始まりました。
そんな旅路の内容と、簡単ではありますが組織にもたらした変化についてお話しできればと思います。

## インフラチームの設立〜SRE実践の準備
やっていき宣言後ほどなくしてインフラチームが設立されました:tada:
"SRE = インフラエンジニア" ではありませんが、一旦はインフラチームを中心に模索していくことに。

「SREの実践」と書きましたが、ガッツリと組織のエンジニアリング文化を変えていくのではなく、直近の目標としては **SLI/SLOの導入と運用ができること** を目指しました。

まずはベースとなる知識と軸を作ることにしました。
なぜそうしたかというと、

- SRE自体に対する知識
- SRE実践のために必要なマインドセット
- SREのプラクティスへの理解

これらがチームメンバー間でギャップがあったためです。
少々遠回りをすることになりましたが、足並みが揃わないことによる空中分解を避けるためにも、まずはこれらの知識/理解を揃え、ブレない軸を作った方がいいと判断しました。
主には以下に取り組みました。

- SRE本/SRW本の輪読会
- 自社におけるSREの定義、ミッションの策定

何をどうやったのか、1つずつ簡単にご紹介します。

### SRE本/SRW本の輪読会
https://www.oreilly.co.jp/books/9784873117911/

https://www.oreilly.co.jp/books/9784873119137/

**正直、めちゃくちゃ大変でした（息切れ）**
なんせ分厚い、こりゃ大変だぞ・・・と読む前にもわかります。
輪読会の開催頻度は週1回、業務時間内であったため時間もかなり限られてきます。
本のボリューム的にも、輪読会の準備自体が継続のハードルになってしまうと思ったため、各自同時に同じ章を読み進めながらGoogleドキュメントに簡単なまとめをし、最後に感想を話し合うスタイルとしました。

**「あれ・・・それ効率悪いんじゃない・・・？むしろ時間掛からない・・・？」**
と思う方もいらっしゃると思います。
正直なところ私は、SRE本はまとめたことを他者へ説明するのが難しい部分が多いな、と感じました。
人それぞれの解釈の違いによる誤った理解を避けるためにも、このやり方でよかったな、と思っています。

また、SRE本/SRW本は、それぞれ以下のように読み進めました。
このようにした理由は、主には時間的な問題です:tired_face:

- SRE本
    - 以下のような章は読み飛ばす
        - Google社内に特化した内容や、少々ポエム的な内容の章（言い方が失礼）
        - 特定のツールについて記されている章
        - 自社のシステムの規模やアーキテクチャ的に、あまり参考にならないと感じた章
- SRW本
    - 「2章 SLOの実装」のみを読む

正直に言いますと、結構な章を読み飛ばす結果となってしまいました。
結果的にそれが良かったのか悪かったのかは、未だわかりません。

:::note info
どの章を読み飛ばすかは、章を読み始める前にまず全体を軽く目を通し、メンバーと話し合いをした上で決定しました。
:::

### 自社におけるSREの定義、ミッションの策定
一言にSREと言っても、人や組織によって解釈、見解は結構異なると思います。
私も当初これといった解が無くモヤモヤし、解を探るためにひたすら他社事例を収集している時期がありました。
しかし、**他社事例を拝見していても三者三様・・・**
組織体制や文化、エンジニアリングスタイル、企業毎にある様々なバックグラウンドを基に、それぞれのSREが実践されているな、と感じました。
解はない、実践することは各社異なると結論付け、自社におけるSREを定義することにしました。

余談ですが、以前はたまに「SREはGoogleだから出来ること」という意見を見かけました。
私自身がそう思っていた時期が無かったといえば嘘になりますが・・・
今となれば、**全てをトレースするのではなく、取り入れられるものは取り入れ、真似できるものは真似し、自社におけるSREを定義、実践していけば良い**、と私は思っています。

ミッションにおいては、自社において実践したいことはもちろん、他社が実践していて「これはいい！」と感じたものは積極的に取り入れるスタイルにしました。

また、SREの定義とミッションの策定はチームメンバーのみではなく、開発組織の部長、マネージャーを巻き込んで行っています。

:::note info
・SREを実践していくにあたり、まず自社における軸を作ったことはGood！
・組織の数だけ文化があるので、組織に合ったやり方を模索することが大切！
:::

## SLI/SLOの策定
ようやく本題です:mask:
SLI/SLOを弊社の主要サービス **引越し侍** に導入すべく、策定に向けて動き始めました。

引越し侍は歴史の長いサービスです。
様々なビジネスロジックやコンテンツ、またシステム的にも複雑な構成になっています。
以下の記事に出会い、SLI/SLOは **システムの境界**に設定するものだと知りました。

>システムの境界にSLIとSLOを設定する

https://newrelic.com/jp/blog/best-practices/best-practices-for-setting-slos-and-slis-for-modern-complex-systems

しかし、当時は境界という境界を決めることができず。
一旦は **"コンテンツ系" "フォーム系"** と、大きく二つのグループを作り、それぞれに対してSLI/SLOを検討していくことにしました。

**コンテンツ系**は、ランディングページ、各種記事ページ、引越し業者さま毎の口コミページ等々が該当します。
**フォーム系**は、以下のような引越し見積もりの依頼フォームが該当します。

https://hikkoshizamurai.jp/request/base

が、このグルーピングには大きな反省点があります。こちらは後述します。
（"改善すべき点" の章を参照）

それぞれのグループには、複数のページURLが含まれます。
各グループでどのページURLを対象とするかは、ビジネス的な重要度（注力度）を加味して検討し、決定しました。

## 策定したSLI/SLO
策定したSLI/SLOを紹介します。

改めて、簡単ではありますが用語の定義をします。

- SLI(Service Level Indicator)
    - サービスのレベル、品質を計測するためのメトリクス
- SLO(Service Level Objective)
    - SLIに対しての目標値
- タイムウィンドウ
    - SLOを測定する期間

:::note warn
以下に記載のSLI/SLOですが、具体的な数値は伏せています。
数値とは、稼働率99%以上、レスポンスタイム1秒以内等のことを指します。

現時点のSLOはあくまで内部的な数値であり、おまけに開発組織内に閉じた数値のため、企業として公表する数値にはなっていません。
SRE本にも記載がありますが、外部にSLOを公表することは、ユーザーのサービスに対する期待を設定することになるため、ここでは具体的な数値は伏せさせていただきます。
:::

### SLI
稼働率、レスポンスタイムの2つを指標にしました。

- 稼働率（正常なリクエストの割合）
    - 正常なリクエスト（HTTP/2xx, 3xx）の割合
- レスポンスタイム
    - パーセンタイルXXのレスポンスタイムがXXXms以下である時間帯の割合

### SLO
計測対象のページURLの直近の状態を確認し、現状のパフォーマンスを把握しつつ、なんとしてもこのラインは守りたい・・・！という数値を設定しました。
タイムウィンドウは、計測時点から過去xx日という**ローリングウィンドウ**を選択しています。
ローリングウィンドウは、カレンダーウィンドウ（具体的な期間を決定して計測する方式）よりもユーザー体験に近しい指標となるためです。

- 稼働率（正常なリクエストの割合）
    - 過去30日間のローリングウィンドウにおいて、正常なHTTPステータスコードを返すリクエストの割合がxx%以上であること
    - 計測間隔: 1日
- レスポンスタイム
    - 過去30日間のローリングウィンドウにおいて、パーセンタイルXXのレスポンスタイムがXXXms以下である時間帯がxx%以上であること
    - 計測間隔: 1時間

:::note info
レスポンスタイムは、平均値ではなくパーセンタイル値で計測しています。
これは、システムにおいてボトルネックとなっているものや、極端に遅いレスポンスによるユーザー体験の悪化に気が付きたかったためです。
平均値を選択するとテールレイテンシーを見逃してしまうため、弊社ではパーセンタイル値を選択しました。
:::

## SLI計測のための仕組み
計測の仕組みについてもご紹介します。
主なコンポーネントは以下の通りです。それぞれの役割を紹介します。

- Amazon OpenSearch Service （旧Elasticsearch Service）
    - SLIを計測するためのソースとなるアクセスログを保管しています
    - SLIの低下やSLO違反が発生した場合に、アクセスログを調査するためにも使用します
- AWS Lambda
    - OpenSearchに対して、SLIを算出するための検索クエリを投げ、結果をNew Relicに格納する関数を動かしています
    - SLIの数値は、New Relicには**メトリクス**として格納しています
- New Relic
    - Lambda関数によって格納されたメトリクスをダッシュボードで可視化しています

:::note info
・上記のコンポーネント（Lambda関数以外）はSLI/SLOのために用意した物ではなく、元々あったものです。
・SRE本にもある通り、既にログを利用して計測を始めると、よりスムーズに進められます。
・New RelicにSLIをメトリクスとして格納しているのは、長期保管したいのと、監視のプラットフォームとして利用していることが主な理由です。
:::

## SLI/SLO策定によって変化したこと
SLI/SLO導入以前は、エラー/不具合による影響が把握しづらく、どの程度の温度感で対応すべきかを決定しづらい状態でした。
エラーが発生していた時間帯からビジネス的なインパクトの概算は算出することは可能ですが、**発生したエラーによってどの程度影響を及ぼしたのかを、定量的に把握しづらかった**ことが要因だと思っています。
もちろん、エラー自体がビジネス的にクリティカルなものであると明確にわかれば、高い優先度で対応されますが、全てのエラーがそうであるとは限りません。

### どのエラーが、どの程度影響があるものかを把握しやすくなった
一言にエラーと言っても様々なパターンがあります。

1. 以前から定常的に発生しているエラー（発生頻度低）
2. 特定の条件下のみで発生するエラー（相当なレアケース）
3. あるリリースを境に発生し始めたエラー

などなど、一般的には (3) が多いのかな？と思います。
SLIの推移を日々モニタリングすることによって、SLIの低下に比較的早く気が付くことができます。
低下の具合によって影響度合いがわかるため、対応の優先度も決めやすくなります。

:::note warn
SLIの推移は日々モニタリングしていますが、このやり方はGoogleが提唱するSLI/SLOの在り方とは異なるものだと認識しています。
べき論を言えば、SLO違反orエラーバジェットの枯渇が発生しない限りは気にせず全力で開発に取り組むべき、だと思います。
しかし現状、SLO違反時のアクションやエラーバジェットポリシーの導入、SLOベースのアラートの整備ができていないので、このような方法を取っています。
:::

### DevとOpsの間に共通言語が生まれた
個人的には、これが何よりの成果/効能かなと思っています。

SLI/SLOが共通言語となり、**以前よりも格段にコミュニケーションが増え、サービスの改善に向けたアクションも多く取れている**と思います。

以前はインフラチームから開発チームに対してPushできることが少なかったのですが、最近では・・・
例えば、インフラチームの朝会でSLIの断続的な低下を発見した場合は、アクセスログを調査し、どのページでエラーが発生しているのかを把握、必要に応じてNew Relic APMで詳細な調査を行なっています。
調査によって発見した問題や、対応の検討を行った方がよさそうな事項については、都度開発者にPushしています。

また、開発チームとは週次で**SLO確認会**を実施しています。
Service Levelダッシュボードを整備しているので、SLI/SLOの状況は両チームでそれぞれ行える状態です。
しかしその場では単に数値を確認するだけではなく、SLI低下を招いている要因の調査や、具体的なアクションについてを議論しています。
**気軽に会話ができる場となっているため、コミュニケーションのハードルも下がったのかなと感じています。**

:::note info
・SLI/SLOが開発チーム、インフラチームの共通言語となり、サービスの改善がより加速した！
・DevとOpsの "優先したいこと" の違いによる対立構造が解消された！（※仲が悪いわけではありません！）
:::

### メンバーからの声
SLI/SLOを導入、運用して数ヶ月経過した後に振り返りを行いました。
その際、実際にSLI/SLOの策定に関わったメンバーから出てきた声を紹介します。

:::note info
・（SLI/SLOを）ダッシュボードで見えるようになったことで、開発メンバーでも毎朝数値を見て異常値がないか見る癖がついてきた
・SLIを設定し、見える化し、毎日見るようにしたことで、致命的な状態に陥る前に発見することができるようになった
・知らないうちにユーザビリティが下がっていることに気づけた
・副次的な効果として調査中に別の不具合に気づくことがいくつかあった
:::

振り返りに参加したメンバーは比較的社歴が長い方ばかりでした。
SLI/SLOの策定、導入によって、以前と比較して**良い変化**をもたらせているなと思えます。 :100:

ただ全てが上手くいっていたわけではなく、見直すべき点、反省点も多く挙がりました。

:::note warn
・SLOを満たしていないときに優先度を上げて対応することがなかなかできなかった、主には工数の問題だが、事業として優先度をあげるべきという説明ができていなかった
・SLOを満たしてない状態がずっと続いてる中で、アクションの優先度が上がっていなかった
・レスポンスタイムの目標に近づけようとしたが、P99どころかP90でさえかなり工数を使った改修を行わないと達成出来なさそうだった
:::

設定したSLOが高すぎた、という問題もありました。
後述しますが、これはSLO自体が "目指したい目標" という、理想像とする数値になってしまっていたことが問題です。
満たしていない状態が継続してしまい、満たしていないことが当たり前、となっていたことはBadです。

## 改善すべき点
主な改善すべき点は以下の通りです。

- SLOが **"何としてでも守る目標"** ではなく **"目指したい目標"** になってしまっている
- グルーピングの問題
- 定期的に見直しをする運用ができていない
- SLI/SLOがユーザー体験に即していない

### SLOが "何としてでも守る目標"ではなく "目指したい目標" になってしまっている
SLOを決定する際は、直近のデータからサービスの現状を把握しておりました。
しかし、到底許容できる状態ではなく **最低でもこのラインは死守したい** という数値を設定してしまいました。
サービスにSLO設定した場合、そういったアプローチを取ることが実際にあるのかは不明ですが、弊社の場合は一部のSLOが形骸化してしまい、達成できない状態が当たり前になってしまいました。

以下のリンクに、このように記載があります。

> サービスの信頼性が上がれば上がるほど、運用コストも高くなります。何とかやっていける最低レベルの信頼性を定義し、それを SLO としましょう。

https://cloud.google.com/blog/ja/products/gcp/availability-part-deux-cre-life-lessons

まさにその通りだと思っており、今後策定するSLO、SLOを見直す際には、何とかやっていけるラインを見定め、策定していこうと思います。

### グルーピングの問題
コンテンツ系、フォーム系というグルーピングについての問題です。
例えばコンテンツ系のグループには

>ランディングページ、各種記事ページ、引越し業者さま毎の口コミページ

と、様々なページURLが含まれます。
ページ毎に作りは異なりますし、当然パフォーマンスも異なってきます。
このグルーピングをした結果、**極端にパフォーマンスが悪いページ**によってSLOが達成できない状況が続いてしまいました。

また、全てのページにおいて同じSLI/SLOが設定されるとも限らないため、大まかなグルーピングはBadだということがわかりました。
この点においては、各ページのビジネス的な重要度や、ユーザーにとっての重要度を加味しつつ、システムの境界を見定めてSLI/SLOの設定ポイントを探っていきたいです。

### 定期的に見直しをする運用ができていない
現時点では **SLOの見直しができていない = SLO自体の運用ができていない** 状態です。
このままではシステム監視と同じで、どんどんと腐っていく（形骸化していく）一方になってしまいます。
また、見直しができていないことは、**SLOとサービスの現状に乖離が生まれる**原因にもなり得ます。

サービスの状況を加味して定期的にSLI/SLOを見直し、継続的に育てていきたいと思います。

### SLI/SLOがユーザー体験に即していない
***「SLI/SLOがユーザー体験に即しているか？」***
これは、[先日開催された SRE Lounge #13](https://sre-lounge.connpass.com/event/227250/)のeurekaさんの発表で気が付くことができました。

https://speakerdeck.com/takumiogawa/slozai-ding-yi?slide=11

まさに、現時点でのSLI/SLOはユーザーハピネスに即していませんし、外型監視と同レベルのものになっています。
以下のリンクでもこのように記載されていました。

> The first step in SLO creation is listing critical user journeys for this business.

https://cloud.google.com/blog/products/management-tools/practical-guide-to-setting-slos

ユーザーあってこそのサービスなので、これではいけません。
SLI/SLOの策定において、開発者を巻き込みつつ **CUJ（Critical User Journey）** を探り、ユーザー体験に即した指標を探っていこうと思います。

## さいごに
非常に長くなってしまいましたが、私と組織が取り組んできたことの大半をお話しできたかなと思います。
まだまだ非常に未熟な状態ではありますが、今後もSREもプラクティスを活用して、自社のサービス、開発組織をより良い状態にしていければなと思っております。

## 次回
[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hikkoshizamurai-connect) 八日目の記事はいかがでしたでしょうか。
明日、9日目は @ysysysys が担当します。どうぞお楽しみに！ :raised_hands_tone1: