セル型アーキテクチャと障害分離
一つの障害が全顧客を巻き込む構造から抜け出せます。完全なスタックの複製であるセルに顧客を分割し、爆風半径を1セル分へ封じ込める原理・ルーティング・独立デプロイの設計を掴めます。
- 1.セルは完全なスタック(計算・キャッシュ・データストア)の独立した複製で、各顧客を1つのセルへ固定する。障害はそのセル内に閉じ込められ、爆風半径が全体の1/Nに有界化される。
- 2.鍵はセル間で状態と運命を共有しないこと。共有データベースや共有依存はセルをまたいで障害を伝える相関故障の経路になるため、セルは自己完結させ、ルーティング層だけを薄く共有する。
- 3.デプロイはセル単位で時間をずらして波及させる。1セルでカナリア検証してから次へ進めることで、不良リリースもセル境界で止まり、相関故障を時間軸で低減する。
なぜ一つの障害が全顧客を巻き込むのか
可用性を語るとき、多くの設計は「個々のコンポーネントの故障率」に注目します。しかし大規模インシデントの本当の痛みは、故障率そのものよりも 爆風半径(blast radius)——一つの障害が何人のユーザーに波及するか——にあります。共有のデータベース、共有のキャッシュ、グローバルなコントロールプレーンに全顧客が相乗りしていれば、たった一つの不良デプロイ、一つの毒入りリクエスト、一つのホットパーティションが、瞬時に全顧客の障害になります。
セル型アーキテクチャ(cell-based architecture) は、この問題に構造で答えます。システムを セル と呼ぶ独立した複製に分割し、各顧客をいずれか1つのセルへ固定する。あるセルが壊れても、影響はそのセルの顧客に閉じ込められ、他のセルは無傷で動き続ける。本記事では、なぜセルが爆風半径を有界化できるのか、何がセル境界を越えて障害を漏らすのか(相関故障)、そしてルーティングと独立デプロイをどう設計するのかを原理から解きほぐします。
セルとは何か:完全なスタックの独立複製
セルとは、サービスを成立させるのに必要な構成要素一式——フロントの計算層、キャッシュ、メッセージキュー、データストアまで——を丸ごと含んだ 自己完結した複製 です。マイクロサービスの分割(/devops/microservices/)がシステムを機能で縦に割るのに対し、セル分割は同じシステムを顧客の集合で横に割ります。両者は直交し、各セルの内部はマイクロサービス群でもよい。
┌──────────────┐
ルーティング層 │ Cell Router │ ← 薄い共有層(マッパだけを持つ)
└──────┬───────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Cell A │ │ Cell B │ │ Cell C │
│ 計算+ │ │ 計算+ │ │ 計算+ │
│ キャッシュ│ │ キャッシュ│ │ キャッシュ│
│ + DB │ │ + DB │ │ + DB │ ← 各セルは独立スタック
└─────────┘ └─────────┘ └─────────┘
顧客 {1..k} 顧客 {k+1..m} 顧客 {m+1..n}
決定的な性質は 状態と運命を共有しないこと(share-nothing)です。Cell A のデータベースが過負荷で倒れても、Cell B・C のデータベースは別物なので無関係に動く。Cell A で発火したカスケード障害(/devops/cascading-metastable-failures/)は、A の内部資源を食い尽くしても B・C の資源には届かない。障害の伝播経路がセル境界で物理的に断たれている——これが分離(isolation)の本質です。
データの シャーディング は「データを分割して負荷を分散する」のが目的で、しばしば共通のクエリ層・共通のオーケストレーションを介します。セルは「障害ドメインを分割する」のが目的で、計算からデータまでの一切を複製して依存を断ちます。シャードはスケールのため、セルは分離のため。セルの内部でさらにシャーディングしてもよく、両者は階層をなします。
爆風半径の有界化:N分割が効く理由
爆風半径を定量で捉えます。全顧客を均等に N セルへ分けると、1セルが完全に落ちたときに影響を受ける顧客は全体の 1/N です。N を増やすほど、単一セル障害の影響は小さくなる。
影響顧客の割合 ≈ (故障したセル数) / N
N=1(セルなし) : 1セル故障 = 100% 障害 ← 共有構成はここ
N=10 : 1セル故障 = 10% 障害
N=50 : 1セル故障 = 2% 障害
ここで重要なのは、個々のセルの故障率が下がるわけではない という点です。セル化は故障の確率を減らすのではなく、故障が起きたときの影響範囲を縮める。1リクエスト・1顧客の体験から見れば、自分の属するセルが落ちる確率は変わりません。しかしサービス全体としては「同時に全員が落ちる」が構造的に起きなくなる。可用性の議論で「平均」ではなく「最悪の同時障害規模」を気にする立場では、これが決定的な改善になります。
N を大きくすると爆風半径は縮みますが、運用面のオーバーヘッド(デプロイ回数、監視対象、容量の切り上げ損)は増えます。各セルには冗長性のための余剰容量が要り、セルが小さく多いほど切り上げの無駄が積み上がる。また顧客1人が1セルの容量を超える「象(elephant)」になると、その顧客はもはや分離できません。実務ではセルあたり数百〜数千顧客、N は数十前後に落ち着くことが多く、爆風半径と運用コストのトレードオフ で N を決めます。
相関故障:セル境界を漏れる障害
セル化が約束する分離は、セル間に共有要素がない限り で成立します。逆に言えば、複数のセルが同じものに依存していると、その共有要素の障害は全セルへ同時に波及する——これが 相関故障(correlated failure) です。N分割の 1/N という嬉しい数字は、相関故障が一つでもあると簡単に 1 へ戻ります。
セル設計で最も注意すべき相関故障の経路を挙げます。
| 相関の源 | なぜセル境界を漏れるか | 対策の方向 |
|---|---|---|
| 共有データベース | 全セルが1つのDBを叩けば、DB障害で全セルが同時に倒れる | DBをセルごとに分離し、セル内に閉じる |
| グローバルなコントロールプレーン | 全セルが同じ制御系に依存すると、制御系の障害が全体に波及する | データプレーンを制御系から切り離し、制御系停止でも処理を継続させる |
| 同時一斉デプロイ | 全セルへ同時に不良リリースを配ると、バグが全セルで同時発火する | セル単位で時間をずらして波及(後述) |
| 共有設定・共有シークレット | 1つの不正な設定変更が全セルに同時反映される | 設定もセル単位で段階配布する |
| 共通ライブラリの欠陥 | 同じバグを全セルが内包し、同じ入力で同時に発火する | デプロイをずらして発火を時間方向にもばらす |
とりわけ危険なのが コントロールプレーンへの依存 です。ルーティングや構成配布を担う制御系が、リクエスト処理の クリティカルパス に居座っていると、制御系の障害がそのまま全セルの障害になります。原則は データプレーンとコントロールプレーンの分離——制御系は「あるべき状態」を計算して各セルへ配るが、いったん配り終えれば、各セルは制御系が落ちても手元の状態で動き続ける(静的安定性, static stability)。制御系の障害時に「変更ができない」のは許容するが、「処理が止まる」のは避ける、という設計です。
セルの前に置くルーティング層は、構造上すべてのトラフィックが通る共有要素であり、これが落ちれば全セルが同時に到達不能になります。だからルーティング層は 極限まで薄く・単純に 保ち、複雑なロジックや重い依存をそこへ入れない。マッピング表の参照とリクエスト転送だけに機能を絞り、それ自体も冗長化する。理想的には DNS や anycast、クライアント側のセル選択など、中央の処理を介さない仕組みへ寄せて、ルーティングの障害ドメインを最小化します。
セルルーティング:顧客をセルへ写す
セルアーキテクチャの心臓は どの顧客がどのセルか を決めるルーティングです。要件は二つ。第一に、同じ顧客は常に同じセルへ写ること(粘着性, stickiness)——でないとデータがセル間に散らばり、分離が崩れます。第二に、ルーティング判断が軽く、中央依存が小さいこと。
方式A: マッピングテーブル方式
顧客ID → セルID の明示的な対応表をルーター(と各クライアント)が保持。
利点: 任意の顧客を任意のセルへ自由に割当・移動できる(リバランスが容易)。
欠点: テーブルの配布・整合が要る。テーブル参照が経路に入る。
方式B: ハッシュ方式
cell = hash(顧客ID) mod N でセルを算出。表が不要で計算だけで決まる。
利点: 状態を持たず軽い。
欠点: N を変えると大半の顧客が別セルへ移り、再配置が大量発生。
方式Bの再配置爆発を抑えるには コンシステントハッシュ を使い、N 変更時の移動を最小化します(/devops/consistent-hashing-load-balancing/)。実務では、柔軟な移動が必要なマルチテナント基盤ではマッピングテーブル方式、均質なワークロードではハッシュ方式、という使い分けが多い。いずれにせよ重要なのは、ルーティングの粒度を テナント(顧客)単位 に揃えることです。粒度をリクエスト単位にすると、同一顧客のデータが複数セルへ分散し、share-nothing が崩れます。
セルの容量超過や偏りに備え、セル移動(cell migration) の手順も設計に含めます。象になった顧客や偏った負荷を別セルへ移すには、移動中の二重書き込みや読み取り切り替えが要り、これは分散システムの中でも難所です。だからこそルーティングはテーブル方式の柔軟性が効く局面があります。
独立デプロイ:相関故障を時間軸で減らす
セル境界は 空間的 な分離を与えますが、デプロイの設計は 時間的 な分離を与えます。不良リリースは、コードを共有する以上どのセルでも同じバグを内包する潜在的な相関故障です。これを全セルへ同時配布すれば、1/N の空間分離は無意味になり、全セルで同時発火します。
対策は セル単位の段階デプロイ(cell-by-cell rollout) です。
1. まず1セル(できれば小さく重要度の低いセル)へだけ新版を配る
2. そのセルのSLI(エラー率・レイテンシ・飽和度)を観測ウィンドウ分だけ監視
3. 健全と判定できたら次のセル群へ波及、また監視……を繰り返す
4. いずれかのセルで異常を検知したら波及を止め、そのセルだけロールバック
これはカナリアリリース(/devops/deployment-strategies/)をセル境界に重ねた形です。決定的なのは、最初のセルでバグが発火しても影響はそのセルの顧客に閉じる こと。空間分離(爆風半径 1/N)と時間分離(一度に1セルずつ)が掛け合わさり、不良リリースの被害は「1セル・観測ウィンドウ分」に二重に有界化されます。各セルの観測ウィンドウの間に十分な「ベイク時間」を取ることが、緩やかに顕在化する不具合(メモリリーク、徐々に溜まる不整合)を次セルへ持ち越さない鍵です。
セル化の効果は「故障率の低減」ではなく 爆風半径の有界化(単一セル障害の影響を 1/N へ)。この 1/N は 相関故障がゼロのときの上限 であり、共有DB・共有コントロールプレーン・一斉デプロイのどれか一つでも残ると 1 へ戻る——ここが最頻出の落とし穴です。原則は3つ。(1) セルは計算からデータまで share-nothing にする。(2) コントロールプレーンをクリティカルパスから外し、制御系停止でもデータプレーンが動く静的安定性を持たせる(/devops/graceful-shutdown-draining/ の継続性と同じ思想)。(3) デプロイはセル単位で時間をずらし、空間分離に時間分離を重ねる。ルーティング層自身が共有の単一障害点になりやすい点も忘れない。
まとめ
- セル型アーキテクチャは、計算・キャッシュ・データストアを丸ごと複製した 独立した share-nothing なセル に顧客を分割し、各顧客を1セルへ固定する設計。障害の伝播経路をセル境界で物理的に断つ。
- 効果は故障率の低減ではなく 爆風半径の有界化。N分割なら単一セル障害の影響は全体の
1/Nに縮み、「全員が同時に落ちる」を構造的に消す。 - この
1/Nは 相関故障がゼロのときの上限。共有データベース、グローバルなコントロールプレーンのクリティカルパス依存、一斉デプロイ、共有設定はセル境界を漏れて1へ戻すため、徹底して断つ。 - ルーティングは顧客単位で粘着的に、軽く・中央依存を小さく。マッピングテーブル方式は柔軟な移動に、コンシステントハッシュ方式は軽量さに向く。ルーティング層自身を薄く保ち単一障害点化を避ける。
- デプロイはセル単位で時間をずらし、空間分離(
1/N)に時間分離(一度に1セル+ベイク時間)を重ねて、不良リリースという相関故障を二重に有界化する。
DevOps/インフラ Article
セル型アーキテクチャと障害分離を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
セル型アーキテクチャ
比較で見る軸
難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 6
導入後に効く点
鍵はセル間で状態と運命を共有しないこと。共有データベースや共有依存はセルをまたいで障害を伝える相関故障の経路になるため、セルは自己完結させ、ルーティング層だけを薄く共有する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- DevOps/インフラ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「セル型アーキテクチャ / 障害分離」に近いか確認する。
- 強みである「セルは完全なスタック(計算・キャッシュ・データストア)の独立した複製で、各顧客を1つのセルへ固定する。障害はそのセル内に閉じ込められ、爆風半径が全体の1/Nに有界化される。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。