Amazon Web Services ブログ

Amazon DynamoDB グローバルテーブルのベストプラクティス – パート 3: AWS Fault Injection Service によるリージョナルレジリエンスの検証

この投稿は、Amazon DynamoDB グローバルテーブルのベストプラクティスに関するシリーズのパート 3 です。パート 1 では、リージョン障害に向けてアプリケーションをどのように準備するかについて議論しました。パート 2 では、リージョン障害時のフェイルオーバー戦略について取り上げました。

この投稿では、AWS Fault Injection Service (AWS FIS) を使用して、DynamoDB グローバルテーブル に対する制御された実験を実行することで、アプリケーションがリージョン障害を期待どおりに処理することを検証する方法を紹介します。AWS FIS は両者で動作が異なるため、マルチリージョン強整合性 (multi-Region strong consistency) (MRSC) と マルチリージョン結果整合性 (multi-Region eventually consistent) (MREC) の両方のグローバルテーブルを取り上げます。

レジリエントなマルチリージョンアプリケーションを構築するには、2 つの異なる課題があります。それは、障害を想定して設計することと、設計が機能することを証明することです。本シリーズの最初の 2 つのパートでは設計について扱いました。この投稿では証明について扱います。

AWS Fault Injection Service

AWS Fault Injection Service は、特定の条件が満たされた場合に実験を自動的にロールバックまたは停止するなど、AWS ワークロード上で実験を実行するためにチームが必要とする制御とガードレールを提供します。実験テンプレート (experiment templates) を定義して、対象とするリソース、注入する障害、実験の期間を指定します。AWS FIS は、定義された影響しきい値を超えた場合に実験を自動的に停止する停止条件を含む、ビルトインされた安全ガードレールとともに障害注入を処理します。

なぜ AWS FIS でテストするのか

DynamoDB グローバルテーブルは、MRSC でも MREC でも、高可用性を備えたマルチリージョンレプリケーションを提供します。定常状態のレプリケーションでは、レプリケーションが中断されたときにアプリケーションがどのように動作するかは分かりません。次のような疑問は、テストなしでは答えるのが困難です。

  • リージョン障害時に DynamoDB がエラーを返した場合、アプリケーションはフェイルオーバーするのか、それともクラッシュするのか?
  • アプリケーションは、フェイルオーバーアクションが必要となる障害を早期に検出できるか?
  • フェイルオーバーメカニズムは、目標復旧時間 (RTO) 内にトラフィックをシフトできるか?
  • 障害が解決した後、復旧したリージョンで DynamoDB レプリケーションがまだキャッチアップ中である可能性があります。アプリケーションは手動介入なしで復旧するか?

AWS FIS の実験により、推測ではなく証拠をもってこれらの質問に答えることができます。

MRSC グローバルテーブルでの AWS FIS 実験の仕組み

MRSC グローバルテーブルに対して aws:dynamodb:global-table-pause-replication アクションを使用して AWS FIS 実験を実行すると、実験リージョンと他のすべてのリージョン間のレプリケーションが一時停止されます。例えば、米国西部 (オレゴン) (us-west-2)、米国東部 (バージニア北部) (us-east-1)、米国東部 (オハイオ) (us-east-2) にレプリカを持つ MRSC グローバルテーブルを考えてみましょう。us-east-2 を実験リージョンとして実験を実行すると、us-east-2 への出入りのレプリケーションが影響を受け、us-west-2 と us-east-1 は通常の動作を継続します。

実験中、隔離されたレプリカは操作の種類に応じて異なる動作をします。

  • 結果整合性のある読み込み (Eventually consistent reads) – 許可され、隔離されたレプリカに対して引き続き機能します。
  • 強整合性のある読み込み (Strongly consistent reads) – クロスリージョンの合意に到達できないため、HTTP 500 エラーを返します。
  • 書き込み (Writes) – クロスリージョンレプリケーションが一時停止されているため、HTTP 500 エラーを返します。
  • コントロールプレーンアクション ( UpdateTable など) – すべてのレプリカリージョンで、テーブル全体にわたってブロックされます。

これらの誘発エラーは、専用の Amazon CloudWatch メトリクス FaultInjectionServiceInducedErrors によって追跡されます。このメトリクスは、実験中および実験後のキャッチアップ期間中に返されたシミュレートされた HTTP 500 エラーをカウントし、TableNameOperation で分解されます。これらの誘発エラーは、SystemErrors メトリクスも同じカウントでインクリメントするため、SystemErrors に対する既存のアラームは実験中に発火することに注意してください。FaultInjectionServiceInducedErrors メトリクスは、実験誘発エラーと有機的なサービスの問題を区別するのに役立ちます。

MRSC 実験のための IAM 権限

MRSC 実験では aws:dynamodb:global-table-pause-replication アクションが使用され、dynamodb:InjectError IAM 権限が必要です。この権限は特定のテーブル ARN にスコープを設定できないため、Resource: "*" で付与する必要があります。実験ロールには、リソースポリシーを管理するための権限 (AWS FIS によってセットアップとテアダウンに内部的に使用されます) と、タグでテーブルを対象とする場合は tag:GetResources も必要です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBTableActions",
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutResourcePolicy",
        "dynamodb:DeleteResourcePolicy",
        "dynamodb:GetResourcePolicy",
        "dynamodb:DescribeTable"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:111122223333:table/my-mrsc-table",
        "arn:aws:dynamodb:*:111122223333:table/my-mrsc-table/*"
      ]
    },
    {
      "Sid": "DynamoDBInjectError",
      "Effect": "Allow",
      "Action": "dynamodb:InjectError",
      "Resource": "*"
    },
    {
      "Sid": "TagLookup",
      "Effect": "Allow",
      "Action": "tag:GetResources",
      "Resource": "*"
    }
  ]
}

MREC グローバルテーブルでの AWS FIS の動作

MREC グローバルテーブルの場合、AWS FIS はリソースポリシーベースのアプローチを使用します。MREC テーブルに対して同じ aws:dynamodb:global-table-pause-replication アクションを実行すると、AWS FIS は、DynamoDB レプリケーション サービスにリンクされたロール (service-linked role) (SLR) がレプリケーション操作を実行することをブロックする deny ステートメントをテーブルのリソースポリシーに動的にアタッチします。具体的には:

  • レプリケーション SLR に対して GetItemPutItemUpdateItemDeleteItemDescribeTableUpdateTableScanDescribeTimeToLiveUpdateTimeToLive をブロックする deny ステートメントがテーブルポリシーに追加されます。
  • レプリケーション SLR に対して GetRecordsDescribeStreamGetShardIterator をブロックする deny ステートメントがストリームポリシーに追加されます。

両方のステートメントには、実験の予想終了時刻のためのビルトインされた安全メカニズムを提供する、時間制限付きの DateLessThan 条件が含まれています。

MRSC との重要な違い: アプリケーションはエラーを認識しません。読み込みと書き込みは、すべてのリージョンでローカルに成功し続けます。停止するのはバックグラウンドのレプリケーションです。あるリージョンでの書き込みが他のリージョンに伝播されなくなり、他のリージョンからの書き込みも隔離されたリージョンに伝播されません。これは以下を意味します。

  • アプリケーションはユーザーの観点からは通常通り機能し続けます。
  • 実験中に書き込まれたデータはリージョン間で乖離します。
  • ReplicationLatency CloudWatch メトリクスは出力されなくなります。
  • 実験が終了すると、AWS FIS は deny ステートメントを削除し、レプリケーションがキャッチアップします。

対象テーブルにまだリソースポリシーがない場合、AWS FIS は実験期間中にポリシーを作成し、実験が完了すると削除します。テーブルにすでにリソースポリシーがある場合、AWS FIS は deny ステートメントのみを挿入し、最後に削除して、既存のポリシーをそのまま残します。

MREC 実験のための IAM 権限

MREC 実験はリソースポリシーベースのメカニズムを使用し、dynamodb:InjectError 権限を必要としません:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBActions",
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutResourcePolicy",
        "dynamodb:DeleteResourcePolicy",
        "dynamodb:GetResourcePolicy",
        "dynamodb:DescribeTable"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:111122223333:table/my-mrec-table",
        "arn:aws:dynamodb:*:111122223333:table/my-mrec-table/*"
      ]
    },
    {
      "Sid": "TagLookup",
      "Effect": "Allow",
      "Action": "tag:GetResources",
      "Resource": "*"
    }
  ]
}

前提条件

開始する前に、以下を確認してください。

  • 複数のリージョンにレプリカを持つ DynamoDB グローバルテーブル (MRSC または MREC)。このウォークスルーでは、us-west-2 (プライマリ)、us-east-1、us-east-2 にある MRSC テーブルを使用します。
  • AWS FIS 実験用の IAM ロール。
  • AWS Command Line Interface (AWS CLI) v2 がインストールされ、設定されていること。
  • CloudWatch ダッシュボードまたは監視ソリューションが整っていること。それなしでは、実験の影響を測定できません。

重要: AWS FIS は実際の AWS リソースに対して実際のアクションを実行します。これが初めての AWS FIS 実験の場合は、本番前環境またはテスト環境で開始することを強く推奨します。本番テーブルに対して実行する前に、実験設計と監視に対する自信を構築してください。

ステップ 1: 定常状態を定義する

実験を作成する前に、アプリケーションにとって「正常」がどのようなものか、また実験中の期待される状態を定義します。

例:

  • 「us-east-2 でレプリケーションが 10 分間一時停止された場合、アプリケーションは 30 秒以内に us-west-2 にフェイルオーバーするので、エンドユーザーが認識するエラー率は 0.1% を超えてはならない。」
  • 「us-east-2 で強整合性のある読み込みが失敗した場合、アプリケーションは結果整合性のある読み込みにフォールバックし、そのリージョンの読み込み操作の p99 レイテンシを 50ms 以下に維持する必要がある。」

ベースラインを確立するために、通常運用中の以下のメトリクスを少なくとも 24 時間記録します。

  • 操作ごとの SuccessfulRequestLatency (p50、p99)。
  • SystemErrors (合計)。ゼロに近い値であるべきです。
  • アプリケーションレベルのエラー率とレイテンシメトリクス。

これらのベースラインを実験中および実験後の同じメトリクスと比較し、基準を評価します。

ステップ 2: AWS FIS 実験ロールを作成する

AWS FIS がグローバルテーブルに対して実験を実行するために引き受けることができる IAM ロールを作成します。このロールには、リソースポリシーを管理する権限 (AWS FIS によって内部的に使用されます) と、MRSC テーブル固有の dynamodb:InjectError 権限が必要です。dynamodb:InjectError には Resource: "*" が必要であることに注意してください。特定のテーブル ARN にスコープすることはできません。

実験ロールポリシー:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBTableActions",
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutResourcePolicy",
        "dynamodb:DeleteResourcePolicy",
        "dynamodb:GetResourcePolicy",
        "dynamodb:DescribeTable"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:111122223333:table/my-mrsc-table",
        "arn:aws:dynamodb:*:111122223333:table/my-mrsc-table/*"
      ]
    },
    {
      "Sid": "DynamoDBInjectError",
      "Effect": "Allow",
      "Action": "dynamodb:InjectError",
      "Resource": "*"
    }
  ]
}

信頼ポリシー:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "fis.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

ステップ 3: 実験テンプレートを作成する

以下のコマンドは、レプリケーションを 10 分間一時停止する実験テンプレートを作成します。停止条件である CloudWatch アラームに注目してください。アプリケーションのエラー率が許容しきい値を超えた場合に、実験を自動的に停止します。

aws fis create-experiment-template \
  --description "MRSC replication pause - 10 minute resilience test" \
  --targets '{
    "myGlobalTable": {
      "resourceType": "aws:dynamodb:global-table",
      "resourceArns": [
        "arn:aws:dynamodb:us-east-2:111122223333:table/my-mrsc-table"
      ],
      "selectionMode": "ALL"
    }
  }' \
  --actions '{
    "pauseReplication": {
      "actionId": "aws:dynamodb:global-table-pause-replication",
      "parameters": {
        "duration": "PT10M"
      },
      "targets": {
        "Tables": "myGlobalTable"
      }
    }
  }' \
  --stop-conditions '[{
    "source": "aws:cloudwatch:alarm",
    "value": "arn:aws:cloudwatch:us-east-2:111122223333:alarm:MRSC-Critical-Error-Rate"
  }]' \
  --role-arn "arn:aws:iam::111122223333:role/FIS-DynamoDB-Experiment-Role"

ARN の代わりにタグでテーブルを対象にすることもでき、これは共通のタグ (例えば Environment: staging) を共有する複数のテーブル間で実験を実行したい場合に便利です。これを行うには、対象定義の resourceArnsresourceTags に置き換えます:

"myGlobalTable": {
  "resourceType": "aws:dynamodb:global-table",
  "resourceTags": {
    "Environment": "staging"
  },
  "selectionMode": "ALL"
}

ステップ 4: 実験を実行する

実験を開始します:

aws fis start-experiment \
  --experiment-template-id EXT1234567890abcdef0

実験ステータスを監視します:

aws fis get-experiment \
  --id EXP1234567890abcdef0

実験が実行されている間、CloudWatch ダッシュボードと、隔離されたリージョンだけでなくすべてのレプリカリージョンでのアプリケーションの動作を観察します。

実験中:

MRSC テーブルの場合:

  • FaultInjectionServiceInducedErrors は、隔離されたリージョン内で誘発された 500 エラーの安定したカウントを操作 (GetItemPutItemQuery など) ごとに表示するはずです。
  • SystemErrors は同じカウントだけ増加します。このメトリクスに対する既存のアラームが発火します。
  • 結果整合性のある読み込みは、隔離されたリージョンで成功し続けるはずです。これを操作でフィルタリングされた SuccessfulRequestLatency の SampleCount で確認します。
  • 隔離されたリージョン内の強整合性のある読み込みと書き込みは、HTTP 500 エラーを返すはずです。
  • 健全なリージョンは通常通り動作し続けるはずです。これらのリージョンで SuccessfulRequestLatency で確認します。
  • リージョナルフェイルオーバーが設定されている場合 (例えば、Amazon Route 53 ヘルスチェックを通じて)、トラフィックが目標 RTO 内に健全なリージョンにシフトすることを確認します。

MREC テーブルの場合:

  • アプリケーションはすべてのリージョンで通常通り動作を続ける必要があります。読み込みと書き込みはローカルで成功します。
  • 健全なリージョン間の ReplicationLatency を監視して、それらが互いの間でレプリケーションを継続していることを確認します。
  • 実験リージョンへの ReplicationLatency メトリクスは出力されなくなります。
  • アプリケーションログにエラーが表示されないはずです。レプリケーションの一時停止はアプリケーションには見えません。

実験終了後:

MRSC テーブルの場合:

  • DynamoDB がレプリケーションを再開して収束する間、FaultInjectionServiceInducedErrors はキャッチアップ期間中に短時間継続する可能性があります。
  • SuccessfulRequestLatency の SampleCount は、以前に隔離されていたリージョンで実験前のレベルに回復するはずです。
  • クライアントが再接続する際のリトライストームについて ThrottledRequests を観察します。

MREC テーブルの場合:

  • 実験リージョンへの ReplicationLatency メトリクスが出力を開始し、レプリケーションのバックログが排出されるにつれて減少するはずです。
  • 実験中に健全なリージョンに書き込まれたデータが、以前に隔離されていたリージョンで読み取れるようになっており、その逆も同様であることを確認します。

両方のテーブルタイプの場合:

  • アプリケーションが手動介入なしで定常状態に戻ることを確認します。
  • コントロールプレーン操作が再び成功するはずです。

ステップ 5: 結果を評価する

実験後、ステップ 1 で定義した基準に戻り、収集したデータと照らし合わせて評価します。次の質問をしてください。

アプリケーションは 500 エラーを適切に処理したか? アプリケーションログで未処理の例外を確認します。エラーがエンドユーザーに伝播した場合は、SDK のリトライ設定を調整するか、サーキットブレーカーを使用したアプリケーションレベルのリトライロジックを追加することを検討してください。

結果整合性のある読み込みは有用なフォールバックを提供したか? 実験中、結果整合性のある読み込みは隔離されたレプリカに対して動作し続けました。アプリケーションが特定の操作で古い読み込みを許容できる場合は、強整合性のある読み込みが 500 エラーを返したときに ConsistentRead=True から ConsistentRead=False に切り替えるフォールバックの実装を検討してください。これにより、トラフィックを健全なリージョンにシフトしている間、リージョン障害中に部分的な可用性を維持できます。

フェイルオーバーメカニズムは作動したか? Route 53 ヘルスチェックまたはカスタムフェイルオーバーメカニズムを使用している場合は、最初の誘発エラーからトラフィックシフトまでの時間を測定します。これを目標復旧時間 (RTO) と比較します。

アラートは発火したか? エラーメトリクスに対する CloudWatch アラームがある場合は、期待されるタイムフレーム内にトリガーされたことを確認します。MRSC テーブルでは、AWS FIS によって誘発されるエラーは FaultInjectionServiceInducedErrors メトリクスと SystemErrors メトリクスの両方を同じカウントでインクリメントすることに注意してください。これは、SystemErrors に対する既存のアラームが AWS FIS 実験中に発火することを意味します。AWS FIS 誘発エラーと有機的なエラーを区別したい場合は、FaultInjectionServiceInducedErrors メトリクスを使用します。エラーソースに関係なくエンドユーザーへの影響を捕捉するため、アプリケーションレベルのエラー率にもアラームを作成することを検討してください。

復旧はクリーンに完了したか? 実験後、アプリケーションが手動介入なしで通常運用に戻ったことを確認します。実験中の書き込みから生じた可能性のあるデータの不整合を確認します。

結果が評価基準と一致しなかった場合、それは成功した実験です。お客様に影響を与える前に、レジリエンスのギャップを特定したことになります。

ベストプラクティス

DynamoDB グローバルテーブルに対して AWS FIS 実験を実行するお客様と協力した経験に基づいて、以下を推奨します。

小さく始めて、反復し、自動化する。 テスト環境内の単一テーブルに対して短い実験 (10〜15 分) から始めます。自信を構築するにつれて、期間を増やし、ステージング環境でテストし、最終的にはチームが観察できる営業時間中に本番環境で実験を実行します。ベースラインが確立されたら、実験テンプレートを保存して定期的に実行します。多くのチームは、AWS FIS 実験を月次または四半期ごとの運用準備レビューに組み込んでいます。レジリエンスは一度限りの達成ではありません。アプリケーションが進化するにつれて、継続的な検証が必要です。

実際のリスクに合わせて実験を設計する。 過去のインシデントとニアミスを確認し、最初にテストする障害シナリオを優先します。仮定 (「リトライロジックが 500 を処理することに自信がある」) に挑戦する実験は、しばしば最も価値のある発見をもたらします。DynamoDB レプリケーションの一時停止と、他の AWS サービスに対する他の AWS FIS アクションを組み合わせて、より現実的な障害シナリオをテストするシナリオベースのテストを検討してください。例えば、クロスリージョン接続シナリオ (Cross-Region Connectivity scenario) は、アプリケーションネットワークトラフィック、S3、DynamoDB、その他のサービスをブロックします。

キャッチアップを含む復旧フェーズを監視する。 実験が終了したからといって観察を止めないでください。DynamoDB がレプリケーションを再開し、保留中の書き込みを処理する実験後のキャッチアップ期間は、アプリケーションの復旧ロジックの問題を明らかにする可能性があります。FaultInjectionServiceInducedErrors メトリクスは、この期間中のエラーも追跡します。実験を成功と宣言する前に、アプリケーションが手動介入なしで定常状態に戻ることを確認します。

FIS 実験ロギングを有効にする: 実験ロギング (experiment logging) を有効にして、実験の実行中に詳細な情報を収集します。実験ロギングはデフォルトで無効になっていることに注意してください。

まとめ

このシリーズのパート 1パート 2 では、DynamoDB グローバルテーブルを使用したリージョナルレジリエンス向けのアプリケーション設計について取り上げました。この投稿では、AWS Fault Injection Service を使用してその設計を検証する方法について説明しました。MRSC テーブルの場合、FIS は実際の障害時にアプリケーションが見るのと同じ HTTP 500 エラーを生成します。MREC テーブルの場合、FIS はバックグラウンドレプリケーションを一時停止します。単一のテーブルと短い期間から始めて、自信を得るにつれて範囲を拡大することをお勧めします。実験を安全にスコープすることに関する詳細は FIS 計画ガイド を、さらなる詳細は DynamoDB 開発者ガイドの 障害注入テスト (Fault Injection Testing) を参照してください。


本記事は 2026 年 05 月 20 日 に公開された “Best practices for Amazon DynamoDB Global Tables – Part 3: Validating regional resilience with AWS Fault Injection Service” を翻訳したものです。

原文: https://aws.amazon.com/blogs/database/best-practices-for-amazon-dynamodb-global-tables-part-3-validating-regional-resilience-with-aws-fault-injection-service/

著者について

Lee Hannigan

Lee Hannigan

Lee はアイルランドを拠点とする AWS DynamoDB チームのシニアデータベースエンジニアです。データモデリング、分散システム、開発者ツーリングにわたる 7 年の経験を持ち、大規模に構築するお客様にとって DynamoDB をよりアクセスしやすくすることに焦点を当てています。

Shiladitya Mandal

Shiladitya Mandal

Shiladitya は、AWS DynamoDB チームのソフトウェア開発マネージャーで、データムーブメントグループを率いています。Amazon に 10 年以上在籍し、分散システムの構築とスケーリングに取り組んできました。シアトルを拠点とする Shiladitya は、グローバルテーブルやその他のクロスリージョン機能を支える DynamoDB のレプリケーションおよびデータムーブメント機能に焦点を当てています。