Google Cloud Platform

エラー バジェットの使い過ぎを解消する : CRE が現場で学んだこと (後編)

前回の『CRE が現場で学んだこと』では、サービスのエラー バジェットと、サービスの信頼性目標、つまり SLO(サービス レベル目標)の遵守状況をエラー バジェットから把握することについて解説しました。エラー バジェットを使い過ぎる理由を把握できたら、次にやるべきことは問題を根本的に解決することです。

エラー バジェットの負債

クレジットカードを使い過ぎてしまい、その代金が毎月ごそっと口座から引き落とされた経験をお持ちではないでしょうか。うまく家計をやりくりするには、毎月の請求額を減らすよう負債をできるだけ支払っていくべきです。エラー バジェットについても同じことが言えます。

エラー バジェットの消費状況を分析し、消費率を高めている原因が特定できたら、新機能を担当している開発者の手を借りてでも、その原因に対処するための準備をしなくてはなりません。対処法としては、QA(品質保証)環境や試験セットを改善し、本番環境への移行前に多くのリリース エラーを見つけ出す方法もあれば、ロールアウトの自動化やモニタリングを改善し、不具合のあるリリースをより迅速に発見しロールバックする方法もあります。

こうしたアプローチの結果として、リリースの頻度が減ったり、リリースごとの変更点が減少してエラー バジェットへの影響が小さくなったりすることもあります。一時的にリリースのスピードを落とすのは、将来的に元のスピードで安全にリリースできるようにするためです。

下流での消費状況を把握する

もう 1 つ考慮すべきことがあります。エラー バジェットの使い過ぎの原因が開発者とは関係のないケースのときです。データセンターやクラウド プラットフォームで障害が発生した場合、開発者はなす術がありません。確かに、エンドユーザーはサービスの停止理由など気にかけないでしょうし、サービスの提供側もエンドユーザーにこれ以上迷惑はかけたくないでしょう。ただ、別の場所で発生した障害で自社の開発者を責めるのは無理があります。上述したように、エラー バジェットの消費状況を分析する際、この点は明確にしておきましょう。

次に、プラットフォームのオーナーに過去の(数値化された)信頼性状況を確認し、サービスの運用にあたって目標とする SLO とどう適合させるかを相談する必要があるかもしれません。その際、プラットフォーム側とサービス側の両方で変更が必要となることもあります。プラットフォームに特定の不具合が発生した場合に備えて、サービス側のシステムでそれを検知し、不具合に耐えられるようなシステムに変更するのです。プラットフォーム側でも検知機能を向上させれば、サービスに影響が出るような障害に迅速に対応してもらうことも可能になります。

プラットフォームが大幅に変更されるようなことは、実際はあまりありません。そのため、今後その障害にどう対応するかは決めておきましょう。障害を重大視するのであれば、影響を受けたクラウドのリージョンからサービスを自動的に他のリージョンにフェイルオーバーさせるオプションを実装(そして実行)するなど、回復力を高めるための対応が必要になります(これに関しては過去のブログ記事で扱っています)。

ソフトウェアのリリースに問題があるケース

分析の結果、エラー バジェットの使い過ぎの主な原因がソフトウェアのリリースだったというケースもあります。確かに、私たち Google の経験から言えば、バイナリのロールアウトは障害の最も大きな理由の 1 つです。この場合、たとえば事後分析は次のような文章から始まるでしょう。「ソフトウェアの新リリースをロールアウトしたら、ユーザーが喜ぶであろう<X>となるはずだったのが、実際には<Y>となってしまい、ユーザーのブラウザでエラーが発生したり、猫の写真が表示できなかったり、1 分間にメールが 100 通戻ってきたりした。」

エラー バジェットをオーバーするような粗悪なリリースが連続しているときの模範的な対応は、新機能のリリースを凍結することです。これは最終手段と考えてよいでしょう。負債を減らす努力が十分な信頼性向上に結びついていないと認めることになるため、ユーザー エクスペリエンスを維持するには変更の頻度を下げることが求められるのです。リリースの凍結により、開発チームには時間や方向性が与えられ、頭を切り替えて信頼性向上に再度集中できるようになります。とはいえ、これはかなり思い切った方法です。

リリースの凍結を避けたい場合は以下のような方法もあります。

  • 合意のもとで機能と信頼性のバランスを調整する : たとえば、いつも 2 週間分の仕事を割り振り、通常はそのうち機能面の開発に 95 %、事後分析への対応やその他の信頼性関連の仕事に 5 % 費やしているとします。SLO が遵守できていない間は、その割合を 50 % ずつにすると決めるのです。

  • サービスをオーバープロビジョニングする : たとえば、ほかのクラウド ゾーンやリージョンにレプリケートするための投資を増やしてみましょう。もしくは、サービスのレプリカを稼働させ、トラフィックの負荷が上昇しても対応できるようにします。ただしこれは、このアプローチがエラー バジェットの消費抑制に有効だと判断した場合のみ有効です。

  • リライアビリティ インシデントが発生したと申告する : 事後分析とエラー バジェットの使用状況を分析し、解決法を探る担当者を決めましょう。こうした解決法を最優先にすると事前に表明しておくことが重要です。

凍結状態の期間

実際に新機能を凍結させる必要があるとしたら、いつまで凍結を続ければよいのでしょうか。一般的には、エラー バジェットの使い過ぎが改善され、同じことが起こらないと確信が持てるまでです。エラー バジェットの計算方法は主に 2 つです。固定された期間で計算する方法と(毎月 1 日~月末)、定期的な間隔で計算する方法です(過去 N 日)。

固定期間でエラー バジェットを計算する場合、エラー バジェットの使い過ぎへの対応は、バジェットをオーバーするタイミングによって決まります。たとえば初日にオーバーすると、その月はずっとリリースを凍結することになります。ただし 28 日目にオーバーしても、実際にリリースをやめる必要はないかもしれません。次のリリースは、エラー バジェットがリセットされた翌月になる可能性があるためです。お客様が月ごとの停止状況を気にしているのなら話は別ですが、これはユーザー エクスペリエンスを最適化するにあたってあまりいい方法とは言えません。

一方、30 日間隔でエラー バジェットを測定すると、可用性 99.9 % のサービスは N-30 の間隔で使用したエラー バジェット分を埋め合わせることになるため、20 分のオーバーとなったときは、20 分の借金分がなくなるまで待たなくてはなりません。つまり、N-29 日に 15 分のバジェットを消費し、N-28 日に 5 分のバジェットを消費した場合、残高をプラスの状態にするには、ほかに障害が起こらないと仮定しても 2 日間待つ必要があります。実際には、バッファーとしてエラー バジェットの 20 % 分が貯まるまで待てば、予期せぬ小規模な障害にも対応できるようになります。

この方法に従ったうえで、月間の全エラー バジェットを 1 日で使い切るような大規模障害が発生した場合は 1 か月間の凍結を余儀なくされますが、実際にはこのようなことは受け入れられないでしょう。ただ少なくとも、リリースのスピードを大幅に緩め、根本的原因の修復に時間を割く必要はあるでしょう(前述の「エラー バジェットの負債」の項を参照してください)。ほかにもアプローチはあります。『CRE が現場で学んだこと』シリーズの過去記事でリリースの停止について解説しており、そこでエスカレーション ポリシーの例を分析しています。

以上のように、定期的な間隔でのエラー バジェット測定は、障害が発生した日にちに応じて対応が異なるということもありません。できる限りこの方法を採用するようお勧めしますが、現在の監視ツールでこのようなデータを収集することは難しいかもしれません。

リリースの凍結による長期的なコスト

新機能のリリース凍結にもコストはかかります。最悪のケースとしては、開発者による新機能の開発が続いているにもかかわらず、それをユーザーにリリースすることはせず、結果として変更点が積み重なり、後でリリースを再開したときに次々と不具合が見つかるということがあります。

これは実際に起こっていることです。たとえば、ブラックフライデーやニューイヤーなどのイベントでサービスの新リリースを凍結すると、その翌週はバックアップしていた変更のすべてがユーザーに届けられることになり、サービスに不具合が発生して非常に忙しくなります。こうした状況を避けるには、凍結の影響を受けるチームに対して、この凍結が機能の開発ではなく信頼性の開発に注力する余裕を持つためのものであることを、再度強調しておくことが重要です。

また、すべてのリリースを凍結することが難しい場合もあるでしょう。カンファレンスなどの大規模なイベントを予定しているときは、直近のユーザー エクスペリエンスがどうであれ、特定の新機能を本番環境にプッシュしなくてはならないこともあります。そこで、このような場合は特効薬を投入することも検討してみましょう。製品管理チームは、重要な機能をデプロイするために、リリースの凍結を無効にできるという(非常に制限された)権利を持っています。特効薬をうまく使う方法としては、この権利の行使には高額な費用がかかるようにし、頻度も制限することですが、特効薬の投入は障害と見なされるべきであり、事後分析を実施してなぜこうなったのか、今後の発生リスクを抑えるにはどうすればよいのかを調べる必要があります。

エラー バジェットを自社(およびユーザー)のために利用する

サービスの信頼性向上に信念を持って取り組んでいるのであれば、エラー バジェットは非常に重要な概念となります。家計の予算と同様に、エラー バジェットは(サービスの所有者が)使うためにあるもので、使い過ぎた場合にどうするかは、実際に予算オーバーとなる前にサービスの利害関係者間で合意しておくことが必要です。

エラー バジェットの使い過ぎが判明したときは、信頼性改善に向けて開発時間を優先させる機能凍結が効果的な方法となるでしょう。ただし、使い過ぎたからといって、反射的にリリースを凍結することが常に適切な対応とは限りません。エラー バジェットがどこで使われたのかを見極め、使い過ぎの発生源を縮小し、財布の紐を緩めるのが適切かどうか考えてみましょう。一番重要な原則は、データに基づいて実施することです。

SRE(サイト信頼性エンジニアリング)についてより詳しく知りたい方は、7 月に米国サンフランシスコで開催される Next '18 にぜひご参加ください。SRE の原則をサービスのデプロイや管理に適用する方法について紹介します。

関連コンテンツ


*この投稿は米国時間 6 月 28 日、Adrian Hilton、Alec Warner、および Alex Bramley によって投稿されたもの(投稿はこちら)の抄訳です。

- By Adrian Hilton, Alec Warner and Alex Bramley