バルクヘッドパターン
システムをリソース的に独立した区画に分離し、障害の影響範囲を限定する耐障害性パターン
バルクヘッドパターンとは
バルクヘッドパターンは、船舶の隔壁 (バルクヘッド) に着想を得た耐障害性パターンで、システムをリソース的に独立した区画に分離し、障害の影響範囲を限定する。Michael Nygard が「Release It!」(2007 年) で体系化した。
船舶は隔壁で船体を複数の区画に分割しており、1 つの区画に浸水しても他の区画には影響しない。同じ原理をソフトウェアに適用し、1 つのコンポーネントの障害がシステム全体に波及するのを防ぐ。
バルクヘッドがない場合の問題
バルクヘッドがない場合の問題を図で示す。
❌ 共有リソース:
注文 API ─┐
検索 API ─┤→ 共有コネクションプール (100 接続) → DB
通知 API ─┘
検索 API が遅いクエリを大量実行
→ コネクションプールを占有
→ 注文 API と通知 API も接続できなくなる
→ システム全体が停止
分離の方法
分離の方法を以下にまとめる。
| 方法 | 説明 | AWS での実装 |
|---|---|---|
| コネクションプール分離 | サービスごとにプールを分ける | RDS Proxy の複数エンドポイント |
| プロセス分離 | サービスごとに Lambda を分ける | Lambda 関数の分離 |
| キュー分離 | 処理ごとに SQS キューを分ける | SQS キューの分離 |
| 同時実行数の分離 | Lambda の予約済み同時実行数 | ReservedConcurrentExecutions |
| アカウント分離 | ワークロードごとに AWS アカウント | AWS Organizations |
Lambda での実装
Lambda の予約済み同時実行数 (ReservedConcurrentExecutions) はバルクヘッドそのものだ。
# SAM テンプレート
OrderFunction:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 100 # 注文処理に 100 を確保
SearchFunction:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 50 # 検索に 50 を確保
NotificationFunction:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 30 # 通知に 30 を確保
検索 API にトラフィックが集中しても、50 の同時実行数を超えるリクエストはスロットリングされる。注文 API の 100 枠は影響を受けない。
SQS によるキュー分離
SQS による キュー分離を図で示す。
注文イベント → 注文キュー (SQS) → 注文処理 Lambda
通知イベント → 通知キュー (SQS) → 通知処理 Lambda
分析イベント → 分析キュー (SQS) → 分析処理 Lambda
キューを分離することで、分析処理が遅延しても注文処理には影響しない。各キューに独立した DLQ (デッドレターキュー) を設定し、障害の追跡も区画ごとに行える。
バルクヘッド vs サーキットブレーカー
バルクヘッドとサーキットブレーカーの違いを以下にまとめる。
| パターン | 目的 | 動作 | タイミング |
|---|---|---|---|
| バルクヘッド | 障害の隔離 | リソースを区画に分離 | 事前 (設計時) |
| サーキットブレーカー | 障害の伝播防止 | 失敗が続いたら呼び出しを停止 | 事後 (障害検知時) |
両方を組み合わせて使うのが効果的だ。バルクヘッドで障害の影響範囲を限定し、サーキットブレーカーで障害が検知された呼び出しを遮断する。
設計時の注意点
- リソースの割り当てを細かくしすぎると、全体の利用効率が下がる。重要度に応じた傾斜配分が現実的
- 区画間の依存関係がある場合、上流の区画が停止すると下流も影響を受ける。依存関係を最小化する設計が重要
- 各区画のリソース使用率をモニタリングし、閾値を超えたらアラートを発報する
より深く学ぶには関連書籍が役立つ。
この記事は役に立ちましたか?
関連用語
サーキットブレーカーライブラリ
外部サービスの障害を検知し、自動的にリクエストを遮断して障害の連鎖を防ぐライブラリ
グレースフルデグラデーション
システムの一部が障害を起こしても、機能を縮退させて全体のサービスを継続する設計手法
フェイルオーバー
障害発生時にスタンバイシステムへ自動的に切り替え、サービスの継続性を確保する仕組み
キューワーカー
メッセージキューからタスクを取り出して非同期に処理するバックグラウンドプロセス
Namespace 分離
Kubernetes の Namespace を使ってリソース、ネットワーク、権限を論理的に分離するマルチテナント戦略
Command パターン
操作をオブジェクトとしてカプセル化し、実行の遅延、キューイング、取り消しを可能にするデザインパターン
関連する記事
障害対応の夜に思い出す、あの本の 1 ページ
本番障害の緊迫した場面で、過去に読んだ技術書の知識が助けてくれた経験はありませんか。「いつか役立つ」知識が「今この瞬間」に変わる読書の価値を考えます。
深夜 3 時のデプロイ前に読み返したい 1 ページ
本番デプロイの直前、最終確認のチェックリストとして技術書の特定のページが役立つことがあります。緊張の場面で頼りになる「お守りの 1 ページ」の見つけ方と活用法。
バグを生むのは知識不足ではなく想像力不足である
バグの多くは、コードを書いた時点で「こういうケースもありうる」と想像できなかったことが原因です。想像力を鍛える読書法と、エッジケースへの感度を高める方法を解説します。