データが決断する:オブザーバビリティでプログレッシブデリバリーを推進する

アプリケーションの新しいバージョンをプッシュしたとしよう。カナリアデプロイが始まり、トラフィックの10%が新しいインスタンスにルーティングされる。チームの全員がダッシュボードを凝視する。うまくいっているのか?失敗しているのか?このまま進めるべきか、それとも止めるべきか?

実際のデータがなければ、それは推測に過ぎない。リリース中の推測は、小さな問題を本番インシデントに変えてしまう。

プログレッシブデリバリー(カナリア、ブルーグリーン、段階的ロールアウトなど、呼び方は何であれ)は、新しいバージョンが実際に健全かどうかを確実に測定する手段があって初めて機能する。続行、保留、ロールバックの判断は、勘や単一のチャートを一目見ただけよりも、もっと確かな根拠に基づく必要がある。

リリース中に重要な4つのシグナル

新しいバージョンがトラフィックを受け始めると、4つのメトリクスが状況の全体像を把握するのに役立つ。これらは特別な測定項目ではない。本番環境で既に監視すべきシグナルそのものだが、プログレッシブリリース中は、新旧バージョン間でこれらをリアルタイムに比較する必要がある。

エラーレート

これは、新しいバージョンに到達した全リクエストのうち、失敗したリクエストの割合だ。アプリケーションが通常0.1%未満のエラーレートで動作しているのに、新しいバージョンの稼働後に突然5%に跳ね上がったら、何かがおかしい。

エラーレートの急上昇は、さまざまな原因で発生する。新しいコードのバグ、動作が変わった依存関係、環境間の設定ミスなどだ。重要なのは、旧バージョンのエラーレートと新バージョンのエラーレートの差を並べて確認できることだ。新バージョンのエラーレートが0.5%でも、単体で見れば問題ないように思えるかもしれない。しかし、旧バージョンが0.05%で動作しているなら、それは10倍の増加であり、調査に値する。

レイテンシ

応答時間の変化は、エラーが発生する前であっても、何かがおかしいことを示す最初の兆候であることが多い。新しいバージョンでは、データベースクエリが遅くなったり、不要な処理ステップが追加されたり、キャッシュの動作が変わったりする可能性がある。ユーザーは数ミリ秒の遅延に気付かないかもしれないが、レイテンシが200ミリ秒から2秒に跳ね上がれば、体感品質は著しく低下する。

レイテンシはサーバー側だけでなく、可能であればユーザー側からも監視すること。サーバー側のメトリクスはアプリケーションの応答速度を示すが、クライアント側のメトリクスはネットワーク遅延やブラウザのレンダリング時間を含む、ユーザーが実際に体験する内容を教えてくれる。

トラフィック

このメトリクスは、ルーティング設定が意図した通りに機能していることを確認する。カナリアがトラフィックの10%を受信するように設定したなら、実際にリクエストの10%が新しいバージョンに到達していることを検証する必要がある。ロードバランサーの設定ミス、スティッキーセッション、キャッシュ層などが原因で、トラフィックが不均等に分割されることがある。

トラフィック量は、新しいバージョンが旧バージョンと同じ負荷を処理できるかどうかも教えてくれる。同じトラフィックレベルで新しいバージョンが接続をドロップしたりリクエストを拒否したりし始めたら、それは明らかにキャパシティ問題の兆候だ。

飽和度

飽和度は、サーバーリソースがどの程度使用されているかを示す。CPU、メモリ、ディスクI/O、データベース接続はすべて監視が必要だ。新しいバージョンが旧バージョンの2倍のメモリを突然使用し始めたら、サーバーのリソースが枯渇してクラッシュする可能性がある。

飽和度はしばしば先行指標となる。エラーレートが急上昇したりレイテンシが増加したりする前に現れる。飽和度を早期に捉えれば、ユーザーに影響が出る前にリリースを一時停止して調査できる。

リリース前に閾値を設定する

これらの4つのメトリクスは、比較対象となる閾値がなければあまり意味がない。「健全」とは何かをリリース開始前に定義しておく必要がある。ストレスが溜まり意見が飛び交うリリースの最中に決めるのでは遅すぎる。

各メトリクスに具体的な数値を設定する。例えば:

  • エラーレートは0.5%未満に保つ
  • 平均レイテンシは旧バージョンと比較して20%以上増加しない
  • CPU使用率は80%未満に保つ
  • メモリ使用量は利用可能容量の90%を超えない

これらの閾値は、既存のサービスレベル目標(SLO)や、アプリケーションが通常どのように動作するかに関する過去のデータから導き出すべきだ。過去のデータがない場合は、控えめな数値から始めて、学習するにつれて調整する。

閾値はトラフィックの割合も考慮する必要がある。5%のトラフィックで動作するカナリアでは、フルロード時のみ現れる問題は検出できないかもしれない。ロールアウトの各段階で異なる閾値を設定するか、サンプルサイズが小さくても異常を検出できる統計的手法の使用を検討しよう。

データに基づいた意思決定

メトリクスが流れ始め、閾値が設定されれば、意思決定プロセスは単純になる。リリースが問題ないかどうかについて議論する必要はない。データが教えてくれる。

すべてのメトリクスが定義された観測期間(例えば5分間の安定したデータ)にわたって安全な範囲内に収まっていれば、次の段階に進む。トラフィックの割合を10%から25%に増やすか、より多くのユーザーを新しいバージョンに移行する。そして再び観測する。

意思決定プロセスは、4つのシグナルとその閾値に基づいた明確なフローに従う:

flowchart TD A[4つのシグナルを監視] --> B{すべて安全な閾値内か?} B -->|はい| C[次の段階に進む] B -->|いいえ| D{クリティカルな閾値を超えているか?} D -->|いいえ| E[リリースを保留、調査] D -->|はい| F[即座にロールバック] C --> G[トラフィック割合を増加] G --> A E --> A

いずれかのメトリクスが警告閾値を超えたが、クリティカル閾値は下回っている場合は、リリースを保留する。トラフィックを増やしてはいけない。まだロールバックもしない。チームに調査する時間を与え、これが本当の問題なのか一時的なスパイクなのかを判断させる。

メトリクスがクリティカル閾値を超えた場合(エラーレートが劇的に急上昇、レイテンシが3倍になる、サーバーのメモリが不足し始めるなど)は、即座にロールバックする。ミーティングを待ってはいけない。承認を求めてはいけない。データが既に決断している。

意思決定ループの自動化

手動による意思決定は、小規模なチームや低リスクのリリースでは機能するが、スケールしない。人間は遅く、一貫性がなく、バイアスに影響されやすい。月曜日に即座にロールバックした同じ人物が、金曜日にはリリースが緊急であるという理由で躊躇するかもしれない。

より良いアプローチは、意思決定ループ全体を自動化することだ。デプロイパイプラインは、オブザーバビリティデータを読み取り、閾値と比較し、人間の介入なしに続行、保留、ロールバックを決定するべきである。

これは、人間をプロセスから完全に排除することを意味しない。人間の関与を最も価値を発揮する場所、すなわち閾値の定義、経時的なパターンのレビュー、自動化が予測できないエッジケースの処理に移すことを意味する。ルーチン的な判断(「このカナリアはトラフィックを増やすのに十分健全か?」)は、まさにコンピュータが人間よりも上手く処理できる種類の判断である。

次回のリリースのための実践的チェックリスト

次回のプログレッシブデリバリーを実行する前に、以下の準備が整っていることを確認しよう:

  • エラーレート、レイテンシ、トラフィック、飽和度のすべてが、新旧両方のバージョンで収集されていること
  • 閾値がリリース開始前に定義され、文書化されていること
  • 観測期間(判断を下すまでの待機時間)が設定されていること
  • 自動ロールバックが設定され、テストされていること(計画だけでなく)
  • 自動化が失敗したり誤検知を生成した場合に何をすべきかを知っているチームメンバーがいること

まとめ

オブザーバビリティは、プログレッシブデリバリーを推測ゲームからデータ駆動型プロセスへと変える。リアルタイムのメトリクス、明確な閾値、自動化された意思決定があれば、「このリリースは安全か?」と問うのをやめ、「データは何と言っているか?」と問い始めることができる。答えは常にダッシュボードとログの中にある。難しいのは、その声に耳を傾けるシステムを構築することだ。