爆弾が爆発した時、ダメージを受ける範囲を「爆発半径(Blast Radius)」と呼びます。
ソフトウェアの障害も同じです。バグやデプロイ失敗が「爆発」した時、どの範囲のユーザーが、どの機能が、どのサービスが影響を受けるか -- これがBlast Radiusです。
「壊れるかどうか」ではなく「壊れた時に何人が巻き込まれるか」を設計する。これが堅牢設計の核心です。
全か無かの恐怖
「デプロイしました」「全ユーザ���に反映されました」「バグがありました」「全ユーザーが影響を受けています」-- この4文を1分以内に全部言った経験、ありませんか。私はあります。
従来のデプロイは「全か無か」でした。
新バージョンをデプロイ → 全ユーザーに即時反映
→ バグがあれば全ユーザーが被害
Blast Radiusを意識すると、こう変わります。
1%に試す → 問題なければ10% → 50% → 100%
→ バグがあっても1%だけが被害
全ユーザー90分影響が、1%ユーザー10分影響に変わる。やっていることは同じデプロイなのに、被害規模が数百分の一になります。
Feature Flags -- 機能のON/OFFを動的に制御
Feature Flagsは、コードをデプロイした後でも機能のON/OFFを動的に制御する仕組みです。Blast Radiusを制御する最も手軽な手段です。
app.get('/dashboard', async (req, res) => {
const user = req.user;
// 新UIは段階的に展開
const useNewUI = await featureFlags.isEnabled('new-dashboard-ui', user);
if (useNewUI) {
return res.render('dashboard-v2', { user });
}
return res.render('dashboard-v1', { user });
});
展開ルールは柔軟に設定できます。
const flags = {
"new-payment-engine": {
enabled: true,
rules: [{ type: "group", groupName: "internal-testers" }]
// まず社内テスターだけ
},
"new-dashboard-ui": {
enabled: true,
rules: [{ type: "percentage", value: 5 }]
// 5%のユーザーだけ
},
"experimental-ai-feature": {
enabled: true,
rules: [{ type: "region", regions: ["jp"] }]
// 日本ユーザーだけ
}
};
問題が発覚したらFlagをOFFにするだけ。デプロイのロールバックより圧倒的に速いです(私の経験では、ロールバックに5分かかる場面でもFlag切り替えなら10秒でした)。
Canary Release -- 1% → 10% → 100%
カナリアリリースは、新バージョンを段階的に展開するデプロイ戦略です。炭鉱でカナリアを使って有毒ガスを検知したことに由来します。
判断基準を自動化すると安全性が上がります。
async waitAndValidate(percentage) {
const waitMinutes = percentage <= 10 ? 5 : 15;
await sleep(waitMinutes * 60 * 1000);
const metrics = await this.metrics.collect('5m');
// エラー率1%超えで自動ロールバック
if (metrics.errorRate > 0.01) {
await this.rollback();
throw new Error('Canary failed - rolled back');
}
// レイテンシ1.5倍超えで自動ロールバック
if (metrics.p99Latency > metrics.baseline.p99Latency * 1.5) {
await this.rollback();
throw new Error('Latency degradation - rolled back');
}
}
人間の判断を待たずにロールバックできるのがポイントです。金曜夜のデプロイでも安心できます(金曜デプロイを推奨しているわけではありません)。
Blue-Green Deployment -- 秒単位のロールバック
2つの本番環境(Blue / Green)を用意し、切り替えるデプロイ戦略です。
Blue環境(現在のアクティブ): v1.0 ← 全トラフィック
Green環境(待機中): v2.0 ← デプロイ済み、ヘルスチェック完了
切り替え: ロードバランサーの向き先をBlue → Greenに変更
問題発覚: 向き先をGreen → Blueに戻す(数秒で完了)
Canary Releaseが「段階的に様子を見る」のに対して、Blue-Greenは「全切り替え+即座に戻せる保険」です。DB schemaの変更がない場合に特に有効です。
Cell-Based Architecture -- AWSの大規模戦略
大規模システムでは、AWSが採用しているCell-Based Architectureが参考になります。
全体システム
├── Cell-A(ユーザー 1〜100万)
│ └── 独立したDB + App
├── Cell-B(ユーザー 100万〜200万)
│ └── 独立したDB + App
└── Cell-C(ユーザー 200万〜300万)
└── 独立したDB + App
Cell-Aに障害が起きても、Cell-B・Cのユーザーは影響を受けません。Blast Radiusが全体の1/3に限定されます。
4つのパターンの使い分け
| パターン | Blast Radius | ロールバック速度 | 導入コスト |
|---|---|---|---|
| Feature Flags | 任意の% | 秒(Flag OFF) | 低 |
| Canary Release | 段階的に拡大 | 分(Pod入替) | 中 |
| Blue-Green | 全 or ゼロ | 秒(LB切替) | 高(2環境) |
| Cell-Based | 1/N | 分(Cell分離) | 最高 |
まずFeature Flagsから始めるのが現実的です。if文1つで始められます。「それってただのif文では?」-- はい、そうです。でもそのif文1つで障害の被害範囲が100分の1になります。Canary ReleaseはKubernetesを使っているなら比較的容易。Blue-GreenとCell-Basedはインフラ投資が必要なので、規模に応じて検討します。
まとめ
Blast Radiusを意識するだけで、障害対応の性質が変わります。「全ユーザーが止まる障害」が「1%のユーザーが10分影響を受ける事象」に変わる。やっているのは同じ機能のリリースなのに。
次にデプロイする時、「このリリースのBlast Radiusは何%か?」と自分に問いかけてみてください。答えが「100%」なら、Feature Flagを1つ入れるだけで状況は変わります。
📘 この記事の内容をさらに詳しく知りたい方へ
ハーネス・エンジニアリング -- AIを"使う"から"操る"へ -- Feature FlagsやCI/CDパイプラインの設計を含む、品質担保の全体像を解説しています