フリート規模のローリング(波・サージ・隔離)
数千台への変更が一斉事故にならない出し方が身につきます。波・セル・爆風半径で展開を区切り、サージ容量と相関障害を避け、自動ヘルスゲートで止める原理を掴めます。
- 1.フリート全体への変更は同時配布すると相関障害になる。台数を波(wave)へ刻み、各波の規模を指数的に広げる(カナリア1台→数%→大群)ことで、不良変更の被害を最初の小さな波へ有界化する。
- 2.展開はリージョン・AZ・セル境界に沿って進める。同一AZや同一セルを一度に更新すると、可用性ゾーンの冗長性が一時的に消える。境界をまたぐ並列度を制限し、爆風半径を1セル分に保つ。
- 3.波の間に自動ヘルスゲートを置き、SLI(エラー率・レイテンシ・飽和度)が閾値を割ったら昇格を止めて自動ロールバックする。更新中はサージ容量を足し、容量割れ起因の相関障害を避ける。
なぜ数千台の一斉更新は事故になるのか
1台のサーバーへ変更を入れるのは簡単です。難しいのは、それを数千台のフリートへ 安全に 広げることです。素朴な発想は「全台へ同時に新版を配る」ですが、これは最悪の設計です。変更がコードである以上、不良版はどの台でも同じバグを内包します。それを同時配布すれば、潜在バグは全台で 同時に発火 し、1/N の冗長性は一瞬で 1——全滅——に落ちます。これは複数台が同じ原因で同時に倒れる 相関障害(correlated failure) の典型で、フリート更新が引き起こす最も大きな事故です。
だから大規模なローリングは、変更を 空間(どの台・どの境界) と 時間(どの順で・どれだけ待って) の両軸で刻みます。被害を最初の小さな範囲へ封じ込め、健全性を確認してから次へ広げる。本記事では、波(wave)の規模設計、リージョン・AZ・セル境界に沿った段階展開、更新中のサージ容量、そして波と波の間で昇格を止める自動ヘルスゲートを、原理から解きほぐします。
1サービスの数十レプリカを順に置き換える「ローリングアップデート」は、フリート規模では一段抽象が上がります。対象は数千台・複数リージョン・複数セルにまたがり、更新単位は「台」ではなく「波」や「セル」になります。デプロイ戦略の基本形(/devops/deployment-strategies/)を、爆風半径と相関障害を主語にして大規模へ拡張したものだと捉えると正確です。
波の規模設計:指数的に広げる
ローリングの中核は 波(wave) ——一度に更新する台のまとまり——をどう刻むかです。鍵は 波の規模を指数的に拡大 することです。
典型的な波の刻み(フリート全体に対する割合)
wave 0 : 1台のみ (カナリア/単一インスタンス)
wave 1 : 1% (小群で本番トラフィック検証)
wave 2 : 5%
wave 3 : 25%
wave 4 : 残り全部(大群)
各波の後にヘルスゲートで健全性を確認 → 通れば次の波へ昇格
なぜ等分(毎回10%ずつ)ではなく指数的なのか。理由は二つあります。第一に 被害の有界化。不良変更が最初の波で露見すれば、影響は1台〜1%に閉じます。最も危険な「未知のバグ」は最初に出会うので、序盤を極端に小さくするほど期待被害が小さくなる。第二に 総所要時間の短縮。健全だと分かった後まで小刻みに進めると展開が何時間も延び、その間ずっと新旧バージョンが混在してリスク窓が開き続けます。序盤を細かく・終盤を粗くすることで、リスクの高い区間だけ慎重にし、安全が確認できた後は一気に畳む。
指数拡大は「最初の小さな波で異常が出る」ことを前提にしています。しかし負荷依存・規模依存の不具合は、小さな波では発火しません。たとえば接続プール枯渇、共有データストアのホットパーティション、サンダリングハード(一斉再起動による突入負荷)は、ある台数を超えて初めて顕在化します。だから各波の昇格判定では、エラー率だけでなく 下流・共有資源の飽和度 も監視し、各波で十分な「ベイク時間」を取って規模依存の劣化が現れる猶予を与えます。
境界に沿って進める:リージョン・AZ・セル
波の 規模 を決めたら、次は どの台を選ぶか——更新の境界です。ここを誤ると、規模を小さくしても可用性を壊します。原則は 障害ドメインの境界に沿って進め、一つの境界を一度に全部更新しない ことです。
第一の軸は 可用性ゾーン(AZ) です。多くのシステムは「2つ以上のAZにレプリカを分散し、1AZ喪失でも稼働継続」を冗長性の前提にしています。ここで同一AZのレプリカを一度に更新すると、更新中はそのAZが実質ダウンしたのと同じ状態になり、別AZで障害が重なれば二重喪失で全停止します。だから 更新の並列度はAZ冗長度より小さく 抑え、同時に触るAZを限定して、常に「健全なAZの定足数」を残します。
悪い例: 3AZのレプリカを一度に全更新
AZ-a [更新中] AZ-b [更新中] AZ-c [更新中] ← 全AZが同時に不安定 = 冗長性ゼロ
良い例: AZを一つずつ更新(AZ単位の波)
wave: AZ-a [更新→検証] → AZ-b [更新→検証] → AZ-c
常に2/3のAZが安定版で稼働 = 1AZ喪失耐性を維持
第二の軸は リージョン です。リージョンは最大の障害ドメインで、リージョン単位で時間をずらして展開すれば、不良変更が1リージョンで露見しても他リージョンへフェイルオーバーできます(/devops/multi-region-failover/)。第三の軸が セル です。セル型アーキテクチャ(/devops/cell-based-architecture/)では、各セルが share-nothing な独立スタックなので、セル単位の波が爆風半径をきれいに 1/N セルへ封じ込めます。波の規模設計(指数拡大)と境界設計(AZ・リージョン・セル)は直交し、両方を満たす展開順——たとえば「小さいセルから1つずつ、各セル内ではAZを一つずつ」——を設計します。
コードのデプロイだけが相関障害の源ではありません。設定(config)・フィーチャーフラグ・シークレット・証明書の一斉反映 は、コードを変えずに全台の挙動を同時に変える、最も見落とされやすい相関障害です。不正な1つの設定値が全台へ瞬時に反映されれば、ローリングの安全策をすべて迂回して全滅します。設定変更も コードと同じく波で段階配布 し、ヘルスゲートを通すのが原則です。同様に、全台の 同時再起動 は復帰時の突入負荷(サンダリングハード)と、暖機前のコールドキャッシュによる相関的なレイテンシ悪化を招くため、再起動も波で刻みます。
サージ容量:更新中に容量を割らない
ローリング中は、更新対象の台が一時的にトラフィックを処理できません。新版の起動・暖機の間、その台はサービス容量から抜けます。ここで容量設計を誤ると、更新そのものが過負荷を引き起こす 自己誘発の相関障害 になります。
方式は大きく二つに分かれます。
| 方式 | やり方 | 容量への影響 |
|---|---|---|
| その場更新(rolling / in-place) | 既存の台を順に止めて新版へ入れ替える | 更新中はその波の台数ぶん容量が減る → 残りに負荷集中 |
| サージ更新(surge / 追い越し) | 新版の台を先に増設してから旧版を落とす | 一時的に容量が増える → 容量割れを起こさない |
その場更新は追加コストがかかりませんが、波の規模ぶん容量が抜けます。ピーク負荷の最中に25%の波を抜けば、残り75%の台へ133%相当の負荷が集中し、飽和すれば全体が連鎖崩壊します。これを避けるのが サージ容量(surge capacity) です。新版の台を先に立ち上げてヘルスチェックを通し、トラフィックを受けられる状態にしてから、初めて同数の旧版を抜く。こうすれば常時容量が維持され、むしろ更新中は一時的に容量が増えます(その分のコストは更新時間に比例して発生します)。
maxSurge と maxUnavailable(更新の同時並列度を縛る2つの旋盤)
maxSurge : 望ましい台数を一時的に何台超過してよいか
maxUnavailable : 同時に何台までサービス不能になってよいか
例) surge=25%, unavailable=0%
→ 先に25%増設して健全化してから旧版を抜く。容量は割れない。
例) surge=0%, unavailable=25%
→ 増設なしで25%を抜いて入れ替え。容量は25%割れる。
肝は、新版を「立ち上げた」ことと「トラフィックを受けられる」ことを区別 することです。プロセスが起動しても、暖機・接続確立・キャッシュ充填が済むまでは健全ではありません。だから旧版を抜く判断は、新版が レディネス(処理可能状態) を示してから下します。プロセス生存だけを見るリブネスと、トラフィック受け入れ可否を見るレディネスを混同すると、暖まっていない台へ送って瞬間的なエラーを出します(/devops/health-check-probes/)。
自動ヘルスゲート:波と波の間で止める
波を刻み、境界を守り、容量を保っても、最後の要——昇格するか止めるかを誰が決めるか——が残ります。人手の目視確認は、数千台・数十波のスピードに追いつけず、夜間や疲労で見落とします。だから波と波の間には 自動ヘルスゲート(automated health gate) を置き、機械が客観指標で昇格を判定します。
ヘルスゲートの原理は、新版の台群(カナリア)と旧版の台群(ベースライン)の SLI を統計的に比較 することです。単に「新版のエラー率が閾値未満か」だけでなく、「新版が ベースラインより有意に悪くないか」を見ます。これにより、たまたま全体が不調な時間帯にカナリアを巻き添えで殺す誤判定を減らせます。
ヘルスゲートが見る代表的なSLI
エラー率 : 新版の5xx率がベースライン比で有意に高くないか
レイテンシ : p50/p99 がベースラインから悪化していないか
飽和度 : CPU・メモリ・接続プール・キュー滞留が逼迫していないか
下流影響 : 依存サービスのエラー・レイテンシが悪化していないか
判定:
全ゲート通過 → 次の波へ自動昇格
いずれか違反 → 昇格を停止(halt)し、自動ロールバック/人へエスカレーション
ここで決定的なのが ロールバックの自動化と高速化 です。ヘルスゲートが異常を検知しても、切り戻しに数十分かかれば被害が広がります。だから新旧を即座に切り替えられる仕組み——トラフィックの瞬時切り戻し、前バージョンへの即時復帰——を用意し、検知から復旧までの時間(MTTR)を最小化します。前進(修正版を急いで出す)より 後退(既知の正常版へ即戻す) を既定にするのが原則です。プログレッシブデリバリ(/devops/progressive-delivery-rollback/)は、この「小さく出す→自動で測る→自動で止める/戻す」を一連の制御ループとして体系化したものです。
昇格を急ぐと、まだ十分なリクエストを処理していないカナリアを「健全」と誤判定します。エラー率のような割合指標は、サンプルが少ないと分散が大きく、偶然エラーゼロに見えるだけかもしれません。だからヘルスゲートの観測ウィンドウは「経過時間」だけでなく「最小リクエスト数に達したか」で区切るのが堅牢です。低トラフィックのサービスでは、規定サンプルが貯まるまで昇格を待つ。エラーバジェット(/devops/error-budget-math/)の考え方を波単位に持ち込み、「この波で消費してよい失敗量」を超えたら止める、と設計すると一貫します。
フリートローリングの本質は 相関障害の回避 であり、手段は 空間と時間の二重の刻みです。(1) 波の規模は指数拡大(1台→1%→数%→大群)で、未知バグの期待被害を序盤に有界化する。(2) 更新は障害ドメイン境界(AZ・リージョン・セル)に沿わせ、一つの境界を一度に全部更新せず冗長性の定足数を常に残す。(3) 更新中は サージ容量(maxSurge で先に増設)で容量割れを防ぎ、旧版を抜くのは新版がレディネスを示してから。(4) 波の間に 自動ヘルスゲートを置き、カナリアをベースラインと統計比較して逸脱で 自動ロールバックする。設定・フラグ・再起動の一斉反映も相関障害源であり、コードと同じく波で配るのが頻出の落とし穴です。
まとめ
- フリート規模の変更を一斉配布すると、不良版が全台で 同時発火 して相関障害になる。安全な展開は変更を 空間(境界)と時間(順序・待機) の両軸で刻む設計。
- 波の規模は 指数的に拡大(1台→1%→数%→大群)。未知バグの期待被害を序盤の小さな波へ有界化しつつ、安全確認後は一気に畳んでリスク窓を短く保つ。負荷・規模依存の不具合はベイク時間で炙り出す。
- 更新は AZ・リージョン・セルの障害ドメイン境界に沿って 進め、一つの境界を一度に全更新しない。常に冗長性の定足数を残し、爆風半径を1セル分・1AZ分へ封じ込める。
- 更新中は サージ容量(maxSurge で先に増設し、新版がレディネスを示してから旧版を抜く)で容量割れを防ぐ。容量割れは更新自体が引き起こす自己誘発の相関障害になる。
- 波の間に 自動ヘルスゲート を置き、カナリアをベースラインと統計比較して逸脱で 自動ロールバック。設定・フラグ・シークレットの一斉反映や一斉再起動も相関障害源であり、コードと同じく波で配る。
DevOps/インフラ Article
フリート規模のローリング(波・サージ・隔離)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
フリート管理
比較で見る軸
難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 6
導入後に効く点
展開はリージョン・AZ・セル境界に沿って進める。同一AZや同一セルを一度に更新すると、可用性ゾーンの冗長性が一時的に消える。境界をまたぐ並列度を制限し、爆風半径を1セル分に保つ。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- DevOps/インフラ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「フリート管理 / ローリングアップデート」に近いか確認する。
- 強みである「フリート全体への変更は同時配布すると相関障害になる。台数を波(wave)へ刻み、各波の規模を指数的に広げる(カナリア1台→数%→大群)ことで、不良変更の被害を最初の小さな波へ有界化する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。