💭

SRE?なにそれ美味しくなさそう、をざっくり理解する

に公開

👋 はじめに

この記事は、SRE という仕組み・役割について、その概要をざっくりと説明するためのものです。

「SRE って初めて聞いた。What is that?」

「SRE って言葉はなんとなく聞いたことあるけど、正直よく分かっていない」

「インフラエンジニアみたいな感じ?」

といったエンジニア・非エンジニアの方に向けて、SRE の全体像を大まかに理解していただくことを目的としています。

逆に、熟練の SRE の方にとっては退屈な内容かも知れません。もし記事の内容に誤りがありましたら、コメントにてお知らせください。

(筆者自身、ベテランの SRE ではなく一介の Web エンジニアですので、どうかお手柔らかにお願いします 🙏)

そもそも SRE って何?

SRE(Site Reliability Engineering)を一言で表せば「サービスの信頼性を継続的に高める仕組みや役割」となります。

元々 SRE とは、Google が自社の巨大なサービス群を安定稼働させるために社内で生み出した概念です。

Google 社が提供する Google 検索、Google Maps、Youtube、といったサービスは毎日世界中で数十億人のユーザーが利用する大規模なサービスであり、当然、これらを安定的にメンテナンスしつつスケールさせていくのは大変なことで、従来の「人手で運用する」スタイルでは到底対応できませんでした。

そこで Google は障害対応・リリース・モニタリングなどの従来の運用業務をソフトウェアによって自動化することで、サービスのスケーリングと信頼性を両立させるアプローチを開発したのです。

後に Google がその考え方を SRE Book という形で世界中に公開したことにより、様々な企業に広まることになりました。

Site Reliability Engineering は直訳すると「サイト信頼性エンジニアリング」となります。「サイト」とはいうものの、実際にはプロダクトやインフラを含むあらゆるサービスに適用されます。

「サイト」という語が残っているのは、これがもともと google.com という検索サイトを安定稼働させるために生まれた概念だからです。

SRE はなぜ必要なのか?

通常、プロダクトは「リリースして終わり」ではありません。

ビジネスの成長のためには、新しい機能を追加したり、UI を使いやすくしたり、継続的にアップデートしていく必要があります。

同時に、ユーザーが安心して使える状態を保つために、システムを止めず壊さず、安定的に稼働させ続ける必要もあります。

しかし、これらはしばしば相反するミッションとなり

「速く新機能をリリースしたい開発(Dev)」と

「システムの安定性を最優先したい運用(Ops)」

の組織的な対立に発展します。

機能を追加すれば壊れるリスクが上昇し、慎重になりすぎると開発スピードが落ちてしまうからです。

さらにサービス規模が拡大すると、リリース作業や障害対応を人手に頼る運用は限界を迎え、スケーリングのボトルネックになってしまいます。

SRE はこれらの課題に対し、自動化・数値化・仕組み化の力で 「速く進化しながら壊れない、しかもスケーラブル」 を組織として実現するためのアプローチなのです。

SRE の重要なコンセプト

📍 信頼性の基準を決める(SLI/SLO/SLA)

サービスの信頼性を高めるのが SRE の目的、と書きましたが、「信頼性が高い」とは一体どんな状態なのでしょうか?

一言で言われてもそれが何を指すのかは人によって解釈が異なります。

例えば、ある動画配信サービスの開発を行うチームを想像してください。

チームのメンバーそれぞれに、このサービスにおける信頼性とは? と聞くと

「動画を最後まで再生できること」

「動画をクリックしてから読み込みが一瞬で行われること」

「動画の画質がいつも 4K で再生されること」

など、人によってイメージするものが違いました。

また、「動画を最後まで再生できる」という項目も

「いついかなる時も動画が途中で止まったら NG」

「たまに途中で止まってもすぐ再読み込みで再生できれば OK」

など、その度合いも人によって解釈が異なりました。

このように、信頼性を高めよう、という目標をチームで共有するならば、信頼性とは?を客観的に数値化し、定量的な目標を定める必要があるのです。

📈 SLI

そこで登場するのが SLI(Service Level Indicator)という概念です。

これはサービスの信頼性を測定するための指標のことで、これによりチームは信頼性を数値的に把握できるようになります。

先ほどの例で考えてみます。

チームは「動画を最後まで再生できる」という項目をサービスの信頼性を示す重要な要素だと考えました。

それを SLI として測定可能にするために、「動画を最後まで再生できた」=「再生開始から完了までの間に中断イベントが一回も発生しなかった」と解釈しました。

これを再生開始リクエストの総数で割れば、「動画を最後まで再生できた割合」を表現することができます。

\text{SLI}_\text{動画を最後まで再生できた} = \frac{\text{再生開始から完了までの間に中断イベントが一回も発生しなかったリクエスト数}}{\text{再生開始リクエスト数}}

この SLI は数値的に表現可能であり、0%-100%の範囲に収まります。これであればチームで共通の指標として扱うことができます。

🎯 SLO

SLI を測定できるようになったら、次はそれをどの程度まで高めるか、を決める必要があります。

それが SLO(Service Level Objective)です。

SLO とは SLI がこの閾値以上(または以下や範囲内)であればサービスの信頼性が高いと言えるだろう、という目標値のことで、SLI と SLO をチームで共有することで今サービスの信頼性は適正なのかということを客観的に評価できるようになります。

動画配信サービスの開発チームは SLO を 99.9% と定めました。つまり、動画を最後まで再生できる割合を 99.9% 以上にする、という目標です。

SLO はどの程度なら適切か、というのはプロダクトの性質や状況によって変わるので一概には言えません。99% と 99.9% ではそれを達成するためのコストが 10 倍違います、となれば 99%を選ぶかもしれませんし、しかしそれによる損失や利益が 20 倍以上違います、となれば 99.9%を選ぶかもしれません。

理想的には完璧(100%)まで持っていきたいと思うかもしれませんが、それは現実的には難しいですし、多くの場合は完璧を目指す意味もありません。

例えばこの動画配信サービスのユーザーは、家のルーターやモバイル端末といった信頼性が 100% よりも低いプロダクトを使ってサービスを利用しているので、動画配信サービスの信頼性が 100% であっても他の要素によってユーザー体験は結局毀損されてしまうからです。

🤝 SLA

SLO は主にチーム内部で共有される目標のことですが、SLA(Service Level Agreement)は顧客との契約に含める信頼性の基準です。

通常は SLO よりも低い基準を用いて、その基準を下回れば一部返金や無料クレジットの提供を行う、などの取り決めをあらかじめ契約書に記載しておきます。

SLA の記載により、顧客が想定するサービスの信頼性、と、サービス提供者が想定するサービスの信頼性のイメージを共有し、顧客に安心してもらいつつ、後々のトラブルを未然に防ぐことに繋がります。

💰 エラーバジェットという考え方

さて、 SLI と SLO を設定すると信頼性を客観的に評価できるようになると説明しましたが、これは裏を返せば「どれくらいなら壊れてもよいか」という許容範囲を定義することでもあります。

この許容範囲のことを エラーバジェット(Error Budget) と呼びます。

動画配信サービスの例で言えば、SLO は 99.9% なので 0.1% は途中で止まってしまっても良いということです。

このエラーバジェット(許容される失敗数)に余裕があれば、チームはリスクをとって新機能をリリースすることができますし、バジェットが枯渇しそう(してしまった)であれば、リリースは控えて改善や安定化を優先すべきです。

例えば、ある時点での直近 30 日間の総再生開始リクエスト数が 100 万件だったとします。

SLO が 99.9% なので、0.1% = 1000 件までの再生中断は許容されます。

もし現時点で中断件数が 100 件であれば、900 件の余裕を残している状態なので、リスクを取りやすい状態です。新機能のリリースを優先するでしょう。

しかし、もし中断件数が 1200 件であれば、200 件分予算を超過してしまっているので、システムの安定化が優先されます。リリースのロールバックやコードの改善を行うでしょう。

エラーバジェットは一度尽きてしまったら二度と取り戻せない、というものではなく、一定期間毎に新しい予算が割り当てられます。

システムの安定化を行なったことで直近 30 日間の 中断件数の SLI が再び SLO を満たす水準まで回復したら、そのタイミングからリリースを再開できるようになります。

このように客観的な指標を用いることにより、Dev と Ops の対立を防ぎつつ、開発速度と安定稼働のバランスを保つことができるのです。

⚙️ 運用作業の自動化(トイルの削減)

SRE は、トイル(Toil) と呼ばれる作業をできるだけ減らすことを重視します。

トイルとは、

「人が手作業で行う運用業務で、同じ手順の繰り返しで、サービス価値の向上にはつながらないもの」

のことです。要はつまらない単純作業、という意味です。

このトイルが蔓延していると、人的リソースの過剰消費によって開発にリソースを割けなかったり、手作業による運用負荷がボトルネックになってサービスのスケールを妨げたり、といった負の効果が表れます。

動画配信サービスのチームを例に考えてみます。

サービスの規模が小さい頃は、エラー率増加のアラートが鳴ればログを開いて原因を調べたり、混雑時にパフォーマンスが落ちたらインスタンスを追加したり、といったことを人間の手作業で行なっていました。

しかしユーザーが増え、毎日数百万件の再生が行われるようになると、

  • 深夜に連続でアラートが鳴る
  • インスタンス追加・ログ調査の作業が毎日何回も発生する
  • ヒューマンエラーで逆に障害を拡大させてしまう

といった問題が発生し、もはや人間の手では対応しきれなくなってしまいました。

このような状況に対応するため(もしくは未然に防ぐため)に、SRE は運用作業をソフトウェアによって自動化し、トイルの撲滅を目指します。

上記の例で言えば

  • 異常検知と自動復旧(Auto Healing)
  • ログ収集・分析の自動化
  • 負荷に応じてサーバー台数を自動調整(オートスケール)

などの仕組みを整備し、運用において人間がボトルネックにならないようにします。

トイルを減らすことで、チームは過剰な運用業務から解放され、サービス改善や新機能の作成など、よりビジネス価値に直結する開発のために時間を使えるようになるのです。

🚨 インシデント対応(ポストモーテム)

SRE においては、インシデント対応もまた重要な論点です。

どれだけ安定化を目指して運用していたとしても、サービス障害は起きるものです。

インシデント対応において重要な点はいくつかありますが、ここでは「障害の振り返り」に焦点を当てて、ポストモーテムというアプローチを紹介します。

ポストモーテムとは、重大なインシデントが発生した後に作成される文書のことで、発生事象、影響範囲、根本原因、タイムライン、再発防止策、などをまとめたレポートです。

ポストモーテムはインシデントが完全に復旧された後に作成され、原因や一連の対応についての分析を行い、今後の改善に繋げていくために使用されます。

この振り返りにおいては 2 点、重要な考え方があります。

1 つは、Blameless(誰も責めない)という文化です。振り返りの際に「犯人探し」や「責任追及」といった議論は行いません。このような議論は改善に繋がらないばかりでなく、真の根本原因を覆い隠してしまいます。

もう 1 つは、仕組みによる改善を考えるということです。人がより注意深く確認する、という解決策は機能しません。ヒューマンエラーは起きるものという前提に立ち、自動化や設計による改善・再発防止を目指します。

このようにして作成されたポストモーテムは定期的にレビューされ、チームの学びとして蓄積されていきます。

まとめ

この記事では、SRE のざっくり入門としてその代表的なアプローチをいくつか紹介しました。

元々は Google の世界規模のサービスを支えるために生み出された考え方ですが、信頼性の評価や 開発速度・安定性のトレードオフ、運用業務の自動化や障害振り返りなど、規模に関わらず多くのチームに役立つ考え方だと思います。

もちろん実際の現場に SRE を導入するためには、ここで紹介した代表的な概念以外にも細やかなテクニックや考え方が必要になるかもしれませんが、SRE という概念を知っていただくきっかけになれば幸いです。

📚 参考図書

「ざっくり」という言葉をお借りしました。100 ページ弱で読みやすく SRE の全体像が分かる
SRE サイトリライアビリティエンジニアリングが”ザックリ”「すっきり」分かる本: Google が実践している新 DevOps 方法論

SRE Book の日本語版。SRE をしっかり学びたい人向け。ボリュームはずっしり
SRE サイトリライアビリティエンジニアリング ―Google の信頼性を支えるエンジニアリングチーム

※上記リンクは Amazon アフィリエイトリンクです

Discussion