- ローンチの定義
- アプリケーションに対して外部から見える変更を行うこと
- 素早いローンチサイクルのためには、スムーズなローンチプロセスが無ければならない
- サービス障害を最小限に抑える
- パフォーマンスを最大化する
- 数百万人のユーザーに届ける
- GoogleではSRE内に専門のコンサルティングチームを作って、新プロダクトや新機能のローンチの技術面を受け持たせることにした
- LCEにはSREと同様の技術が求められ、強力なコミュニケーション及びリーダーシップのスキルを持つことが期待される
- 信頼性の基準とベストプラクティスに沿っているかを監査
- 信頼性を高めるための具体的なクションを提供する
- ローンチに関わる複数のチーム間の連絡役として働く
- ローンチが「安全」だという判断を行う門番の役割
- それらの社内教育
- SREの役割の一つなので、他の懸念事項よりも信頼性を優先することが奨励される
- 信頼性の目標が異なる企業なら、インセンティブの構造を異なるものにすると良いかもよ
- LCEにはSREと同様の技術が求められ、強力なコミュニケーション及びリーダーシップのスキルを持つことが期待される
- ローンチエンジニアがいることのメリット
- 幅広い経験
- 組織横断的な視点
- 客観性
時間をかけて見出してきた、良いローンチのプロセスを特徴づける条件
- 軽量であること
- 開発者への負担が低い
- 頑健であること
- エラーが補足されるべき
- 綿密であること
- 重要な細部の扱いに一貫性と再現性がある
- スケーラブル
- 多数のシンプルなローンチも、少数の複雑なローンチも行える
- 適応性があること
- 一般的な種類のローンチも新しい種類のローンチもうまく扱える
- 新しい種類: 例えばChromeブラウザやGoogle Fiberの最初のローンチ
- 一般的な種類のローンチも新しい種類のローンチもうまく扱える
相反するこれらの条件を満たすための方策
- 単純さ
- 基本を正しく理解し、あらゆる不測の事態に備えようとしない
- 個別対応のアプローチ
- 経験を積んだエンジニアが、個々のローンチに合わせてプロセスのカスタマイズを行う
- 高速な共通パス
- 常に共通のパターンをたどる種類のローンチを特定し、その種類のローンチに対するシンプルなプロセスを作成する
- 新しい国でのプロダクトのローンチなど
- 常に共通のパターンをたどる種類のローンチを特定し、その種類のローンチに対するシンプルなプロセスを作成する
私達の経験によれば、エンジニアは重荷となるプロセスや、十分な価値を生まないプロセスを回避するものです。
だからローンチの体験を継続的に最適化するし、コストとメリットの適切なバランスを取るようにする
- Googleではほぼすべてのグループが共通のローンチプロセスに参加している
- ローンチチェックリストが共通のインフラストラクチャへの収束を促す手段の一つとなっている
- 例:共通レート制限システムを用意すれば、レート制限に関する長いチェック項目が1行になる
- ローンチを行うチームに対して提供するチェックリストの一例
- 確認事項:ドメイン名は必要?
- アクションアイテム:マーケティングと調整を行い、ドメインの登録を申請する。フォームへのリンクは以下
- 確認事項:永続化されたデータほ保存する?
- アクションアイテム:バックアップが実装されていることを確認。バックアップを実装する手順は以下
- 確認事項:ユーザーがサービスを乱用する可能性はある?
- アクションアイテム:レート制限とクォータを実装すること。以下の共通サービスを使うこと
- 確認事項:ドメイン名は必要?
- 実際にはこういうチェックリストはほとんど無限にあるので、管理不能な大きさになってしまいがち。
- チェックリストの増大を抑制するために、Googleではローンチチェックリストへの確認事項の追加には、バイスプレジデントの承認が必要だった時期もありました
- 現在の項目追加のガイドライン
- 確認事項の重要性は実証済みでなければならない
- 以前のローンチの大きな失敗に基づいていることが望ましい
- 開発者が実行できるよう、すべての支持は具体的で、実践的で、合理的でなければならない
- 確認事項の重要性は実証済みでなければならない
- チェックリストを適切かつ最新の状態に保ち続けるために
- LCEがチェックリストの選定を継続的に行う
- 年に1、2回、チームのメンバーがチェックリスト全体をレビューして現状に合わせて更新
- 前例のない(予想外の)ローンチ
- 例えばAndroidのローンチの前には、Googleが直接コントロールしないコンシューマデバイスを扱った経験がほとんど無かった
- ウェブサービスみたいに数時間でローンチできない
- 既存のチェック項目の 意図 を念頭に置き、無意味な項目を考えなしに適用しないようにすることが重要
- 例えばAndroidのローンチの前には、Googleが直接コントロールしないコンシューマデバイスを扱った経験がほとんど無かった
チェックリストの開発の具体例
- アーキテクチャと依存関係
- サービスが共有のインフラを適切に使用しているかを確認し、ステークホルダーとして関わってもらうべき共有インフラの担当者を判断
- 確認事項の例
- ユーザーからフロントエンド、バックエンドに至るリクエストのフローはどうなっているか?
- レイテンシに対する要求が異なる複数の種類のリクエストがあるか?
- アクションアイテムの例
- ユーザーに直接関わるリクエストとそうでないリクエストは分離する
- 予想されるリクエスト数の検証を行う。1回のページビューが大量のリクエストを発生させることもある。
- 統合
- アクションアイテムの例
- サービスの新しいDNS名のセットアップ
- サービスと通信するためのロードバランサーのセットアップ
- 新しいサービスのためのモニタリングのセットアップ
- アクションアイテムの例
- キャパシティプランニング
- 新機能のローンチは一時的に大きなスパイクになりうる
- 100%のキャパシティで3箇所にレプリケーションすることにした場合、実際には4〜5箇所を管理して冗長化する
- データセンターやネットワークはリードタイムが長いので、先立って要望を出しておく
- 確認項目の例
- このローンチはプレスリリース、広告、blogポスト、あるいはその他のプロモーションに結びついているか?
- ローンチ時とその後について予想されるトラフィックと成長のレートは?
- トラフィックを捌くのに必要なコンピュートリソースはすべて確保できているか?
- 障害の形態
- 確認事項の例
- 設計中に単一障害点はあるでしょうか?
- 依存対象が利用できない場合の緩和策は?
- アクションアイテムの例
- 処理に長時間を要するリクエストによってリソースが枯渇してしまうことを避けるため、リクエストのタイムアウトを実装する
- 過負荷の状況下では早めに新しいリクエストを拒否するような負荷の削減処理を実装する。
- 確認事項の例
- クライアントの動作
- ユーザーのリクエストだけならユーザー数に比例してリクエスト数が増えるが、スマホの定期バックアップ等を考えると、攻撃的な挙動でサービスの安定性はきはめて簡単に危機に瀕する
- 確認事項の例
- オートセーブ/オートコンプリート/ハートビートの機能はあるか?
- アクションアイテムの例
- 障害時にクライアントが必ず指数的にバックオフするようにする。
- 自動的に発行されるリクエストには必ずゆらぎを入れる。
- プロセスと自動化
- 確認項目の例
- サービスを動作させ続けるために必要な手作業のプロセスはあるか?
- アクションアイテムの例
- 手作業のプロセスをすべてドキュメント化する
- サービスを新しいデータセンターに移動させるプロセスをドキュメント化する。
- 新しいバージョンのリリースを構築するためのプロセスを自動化する。
- 確認項目の例
- 開発のプロセス
- Googleではほぼすべての開発プロセスがバージョン管理システムと深く統合されている
- 設定ファイルもバージョン管理
- アクションアイテムの例
- すべてのコードと設定ファイルはバージョン管理システムにコミットする。
- リリースごとに新しいブランチを切る。
- 外部の依存関係
- サードパーティがメンテナンスしているコードや、他の企業が提供しているサービス
- 確認事項の例
- サービスやローンチが依存しているサードパーティのコード、データ、サービス、イベントは?
- ローンチするサービスに依存するパートナーはいるか?もしいる場合、そのパートナーにローンチの通知をする必要があるか?
- ベンダーがローンチの絶対的な期限に間に合わなかった場合、どうなるのか?
- ロールアウトの計画
- 信頼性の観点から見れば、大規模ローンチは理想的とはいえない
- マーケティングやPRからの外部的な要求に寄って、そう言ってられない場合もある
- カンファレンスのキーノートの瞬間にローンチするなど
- 間に合わなかったら「近日中にローンチします」というスライドに変えるという緊急対策も含めて用意しておく
- アクションアイテムの例
- サービスのローンチに必要なアクションが明記されたローンチ計画を立てる。それぞれのアクションの責任者を明記する。
- ローンチの各ステップにおけるリスクをはっきりさせ、緊急対策を立てておく。
- 逐次的かつ段階的なロールアウト
- Googleにおけるローンチには「ボタン一発」のようなものはほとんどありません
- 時間を書けてローンチを徐々に行うことによってリスクを最小限に抑えるパターンを開発してきた
- まず1つのデータセンターの少数のマシンにインストールして観察
- それから1つのデータセンターのすべてのマシンにインストールして観察
- その後に全社的にすべてのマシンにインストール
- カナリアテスト
- 新しいソフトウェアのインストールを管理するためのツールが、新しく起動されたサーバーをしばらく監視し、クラッシュ等の異常があればロールバックする
- Androidのアプリも逐次的ロールアウト
- 招待システムも逐次的ロールアウトの一種
- 逐次的ロールアウトとは別に、一部のユーザーにだけ機能をリリースする機能フラグフレームワークを持つプロダクトがある
- ユーザーインターフェースへのちょっとした変更をチェックするなど
- 数百個も並行してテストが行われる
- 機能フラグフレームワークは通常以下のような要求を満たす
- 多くの変更の並列ロールアウト
- 一部のサーバー、ユーザー、デバイス、データセンター
- 1%〜10%の間で逐次的に増やしていける
- ユーザー、セッション、オブジェクト、場所に応じてトラフィック送れる
- ユーザーに影響を及ぼすことなく新しいコードパスの障害を自動的に処理できる
- 深刻なバグや副作用があったら即座に変更を独立してロールバックできる
- それぞれの変更によるユーザー体験の改善度合いを計測できる。
- 多くの変更の並列ロールアウト
- 主にユーザーインターフェイス向けとサーバーサイド及びビジネスロジック向けと大きく2つに分類できる
- ステートレスなサービスでは、クッキーや同様のハッシュ値の範囲での振り分け
- ステートフルなサービスでは、ユーザーIDや、アクセスするリソースのIDでの振り分け
- 攻撃的なクライアントの挙動
- 例えば600秒ごとに行うはずの動機を60秒ごとに行ってしまった
- サービスが過負荷で失敗したリクエストをリトライしようとすると、さらに負荷をかけることになる
- 指数的にリトライ感覚を大きくして頻度を下げるべき
- 4xxのHTTPエラーではリトライすべきではない
- 更新をダウンロードするタイミングを夜2時にしてしまうと、その時間にダウンロードサーバーへのリクエストが集中する
- ランダムにすべき
- リトライにおいても単純に1秒後、2秒後、4秒後のようにするよりも、ランダム性を持たせるべき
- クライアントの挙動をサーバーサイドから制御するのは重要
- 定期的にサーバーを確認し、設定ファイルをダウンロードさせ、特定機能の有効化や、同期の頻度などのパラメータを与える
- 機能リリースも設定ファイルで有効化すると、ローンチに関わるリスクを大きく削減できる
- ただし複数のバージョンの組み合わせ爆発に注意
過負荷時の挙動を原理原則から予測するのは難しい → 負荷テストには計り知れない価値があり、ほとんどのローンチに必須
- 単純なモデルでは、CPU使用率は負荷に対して比例するが、現実にはそうではない
- 多くのサービスでは負荷がかかっていない状況でははるかに低速
- CPUのキャッシュやJITのキャッシュ、サービス固有のデータのキャッシュの影響
- 負荷が大きくなるに連れて、ある程度そのサービスのCPUの利用率と負荷は比例していき、レスポンスタイムはほぼ一定になる
- 過負荷に近づくと比例しなくなる
- レスポンスタイムが増大していったり、極端な場合はサービスが完全に固まってしまう
- LCEは最初は自主的な活動だった
- チェックリストを用意し、新しいプロダクトのローンチの数日から数週間前に「ローンチレビュー」をしていた
- 2年間でチェックリストはとても長く複雑になり、経験の浅いSREが変更に対して過度に慎重になったり反対することがでてきた
- プロダクト/機能のローンチの速度が低下してしまう危険にさらされていたため、LCEを発足させた
- このチームの職務は、新しいプロダクトや機能のローンチを加速すると共に、一方でSREの専門知識を活かして高可用性と低レイテンシを持つ信頼性の高いプロダクトをリリースできるようにすること
- 5人のLCEで1500回のローンチを行った
- LCEの業務はとても複雑で、トレーニングにはおよそ6ヶ月必要
- いかにレビューをスムーズにするか
- 低リスクのローンチを特定できるようにして、チェックリストを簡素にした
- 2008年はレビューのうち30%が低リスク
- 低リスクのローンチを特定できるようにして、チェックリストを簡素にした
- Googleが大規模になるにつれて、ローンチの制約が取り除かれたものもある
- 例えばYouTubeを買収したことで、多くのプロダクトは「隙間に収まる」ようになり、複雑なネットワークキャパシティプランニングやプロビジョニングのプロセスが不要になった。
- 1つの建物で複数の従属するサービスをホストできる大規模なデータセンターも構築した
- 複数の既存のサービスに依存し、それらの大量のキャパシティを必要とするような新プロダクトのローンチがシンプルになった
-
- LCEの枠をはるかに超えており、全社的な努力が必要
- スケーラビリティの変化
- プロダクトが急激に成長してアーキテクチャを構築し直すとき
- 運用不可の増大
- 運用にかかわる手作業のエンジニアリング
- それらの発生源を取り除くための直接的な努力が必要
- 運用にかかわる手作業のエンジニアリング
- インフラストラクチャの急速な変化
- インフラストラクチャ(例えばクラスタ管理、ストレージ、モニタリング、ロードバランシング、データ転送)が変化していく
- 「同じ場所にとどまり続けるためだけに必死に走り続けなければならない」
- 解決策:新しい機能へのクライアントの意向を自動化するまで、インフラストラクチャのエンジニアは後方互換性を持たない機能をリリースしてはならない
LCEチームは、変化を妨げることなく安全を実現するという問題に対するGoogleの回答です。