バルクヘッドパターン

システムをリソース的に独立した区画に分離し、障害の影響範囲を限定する耐障害性パターン

耐障害性設計パターン

バルクヘッドパターンとは

バルクヘッドパターンは、船舶の隔壁 (バルクヘッド) に着想を得た耐障害性パターンで、システムをリソース的に独立した区画に分離し、障害の影響範囲を限定する。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 サーキットブレーカー

バルクヘッドとサーキットブレーカーの違いを以下にまとめる。

パターン目的動作タイミング
バルクヘッド障害の隔離リソースを区画に分離事前 (設計時)
サーキットブレーカー障害の伝播防止失敗が続いたら呼び出しを停止事後 (障害検知時)

両方を組み合わせて使うのが効果的だ。バルクヘッドで障害の影響範囲を限定し、サーキットブレーカーで障害が検知された呼び出しを遮断する。

設計時の注意点

  • リソースの割り当てを細かくしすぎると、全体の利用効率が下がる。重要度に応じた傾斜配分が現実的
  • 区画間の依存関係がある場合、上流の区画が停止すると下流も影響を受ける。依存関係を最小化する設計が重要
  • 各区画のリソース使用率をモニタリングし、閾値を超えたらアラートを発報する

より深く学ぶには関連書籍が役立つ。

この記事は役に立ちましたか?

関連用語

関連する記事