

# 障害を防ぐために分散システムでの操作を設計する
<a name="design-interactions-in-a-distributed-system-to-prevent-failures"></a>

 分散システムは、サーバーやサービスなどのコンポーネントを相互接続するために通信ネットワークに依存しています。これらのネットワークでデータ損失や遅延が発生しても、ワークロードは確実に動作する必要があります。分散システムのコンポーネントは、他のコンポーネントやワークロードに悪影響を及ぼさない方法で動作する必要があります。これらのベストプラクティスは障害を防ぎ、平均故障間隔 (MTBF) を改善します。

**Topics**
+ [REL04-BP01 依存している分散システムの種類を特定する](rel_prevent_interaction_failure_identify.md)
+ [REL04-BP02 疎結合の依存関係を実装する](rel_prevent_interaction_failure_loosely_coupled_system.md)
+ [REL04-BP03 継続動作を行う](rel_prevent_interaction_failure_constant_work.md)
+ [REL04-BP04 変更操作をべき等にする](rel_prevent_interaction_failure_idempotent.md)

# REL04-BP01 依存している分散システムの種類を特定する
<a name="rel_prevent_interaction_failure_identify"></a>

 分散システムには、同期、非同期、またはバッチの 3 つの種類があります。同期システムは、リクエストを可能な限り迅速に処理し、HTTP/S、REST、またはリモートプロシージャコール (RPC) プロトコルを使用して同期リクエスト呼び出しと応答呼び出しを行うことで相互に通信する必要があります。非同期システムは、個々のシステムを結合することなく、中間サービスを介して非同期的にデータを交換することによって相互に通信します。バッチシステムは大量の入力データを受け取り、人の介入なしに自動データプロセスを実行し、出力データを生成します。

 **望ましい結果:** 同期、非同期、バッチの依存関係と効果的に相互作用するワークロードを設計します。

 **一般的なアンチパターン:** 
+  ワークロードは依存関係からの応答を無期限に待つため、リクエストが受信されたかどうかが不明なまま、ワークロードクライアントがタイムアウトすることがあります。
+  ワークロードは、相互に同期呼び出しを行う一連の依存システムを使用しています。これには、チェーン全体で正常に処理が行われる前に、各システムが利用可能な状態にあり、システムでリクエストを正常に処理する必要があるため、動作が脆弱になり、全体的な可用性が損なわれる可能性があります。
+  ワークロードは依存関係と非同期で通信し、重複したメッセージを受信する場合が多いのにもかかわらず、1 回のみのメッセージ処理が保証されるという概念に基づいています。
+  適切なバッチスケジューリングツールを使用していないため、ワークロードは同じバッチジョブを同時に実行します。

 **このベストプラクティスを活用する利点:** 特定のワークロードでは、同期、非同期、バッチのいずれかの通信スタイルを 1 つ以上実装するのが一般的です。このベストプラクティスは、それぞれの通信スタイルに関連するさまざまなトレードオフを特定し、ワークロードが依存関係の中断に耐えられるようにするのに役立ちます。

 **このベストプラクティスを活用しない場合のリスクレベル:** 高 

## 実装のガイダンス
<a name="implementation-guidance"></a>

 以下のセクションでは、各種類の依存関係に関する一般的な実装ガイダンスと固有の実装ガイダンスの両方について説明します。

 **一般的な質問、または機能要望** 
+  依存関係が提供するパフォーマンスと信頼性のサービスレベル目標 (SLO) が、ワークロードのパフォーマンスと信頼性の要件を満たしていることを確認します。
+  [AWS オブザーバビリティサービス](https://aws.amazon.com/cloudops/monitoring-and-observability)を使用して[応答時間とエラー率をモニタリング](https://www.youtube.com/watch?v=or7uFFyHIX0)し、依存関係がワークロードに必要なレベルでサービスを提供していることを確認します。
+  依存関係と通信する際に、ワークロードが直面する可能性のある課題を特定します。分散システムには、アーキテクチャの複雑さ、運用上の負担、コストが増加する可能性のある[さまざまな課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/)があります。一般的な課題には、レイテンシー、ネットワークの中断、データ損失、スケーリング、データ複製の遅延などがあります。
+  堅牢なエラー処理と[ログ記録](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)を実装して、依存関係で問題が発生した場合の問題のトラブルシューティングに役立ててください。

 **同期依存関係** 

 同期通信では、ワークロードは依存関係にリクエストを送信し、応答を待っている操作をブロックします。依存関係がリクエストを受け取ると、すぐに処理を試み、応答をワークロードに送り返します。同期通信の大きな課題は、一時的な結合が発生するため、ワークロードとその依存関係を同時に利用できるようにする必要があることです。ワークロードで依存関係との同期通信が必要な場合は、以下のガイダンスを検討します。
+  ワークロードが 1 つの機能を実行するために複数の同期依存関係に依存するべきではありません。リクエストを正常に完了させるためにパス内のすべての依存関係が利用可能である必要があるため、依存関係の連鎖は全体的な脆弱性を高めます。
+  依存関係が正常でない場合や利用できない場合のエラー処理と再試行戦略を決定します。バイモーダル動作の使用は避けてください。バイモーダル動作とは、通常モードと障害モードでワークロードが異なる動作を示す場合をいいます。バイモーダル動作の詳細については、「[REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html)」を参照してください。
+  ワークロードを待機させるより、フェイルファストの方がよいことを覚えておいてください。例えば、「[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/invocation-retries.html)」では、Lambda 関数を呼び出すときに再試行や失敗を処理する方法について説明します。
+  ワークロードが依存関係を呼び出す際のタイムアウトを設定します。これにより、応答を待つ時間が長すぎたり、無期限に待ったりすることを回避できます。このトピックに関する役立つ説明は、「[レイテンシーを考慮した Amazon DynamoDB アプリケーションのための AWS Java SDK HTTP リクエスト設定のチューニング](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/)」に記載されています。
+  1 つのリクエストを処理するためのワークロードから依存関係への呼び出し回数を最小限に抑えます。呼び出し回数の多さは、結合とレイテンシーの増加につながります。

 **非同期依存関係** 

 ワークロードを依存関係から一時的に切り離すには、非同期で通信する必要があります。非同期アプローチを使用すると、ワークロードの依存関係や一連の依存関係からの応答の送信を待つことなく、他の処理を実行できます。

 ワークロードで依存関係との非同期通信が必要な場合は、以下のガイダンスを検討します。
+  ユースケースと要件に基づいて、メッセージングとイベントストリーミングのどちらを使用するかを決定します。[メッセージング](https://aws.amazon.com/messaging/)を使用すると、メッセージブローカーを介してメッセージを送受信することで、ワークロードが依存関係と通信できます。[イベントストリーミング](https://aws.amazon.com/streaming-data/)を使用すると、ワークロードとその依存関係は、ストリーミングサービスを使用して、できるだけ早く処理する必要のあるデータを継続的なストリームとして配信されるイベントを公開およびサブスクライブできます。
+  メッセージングとイベントストリーミングではメッセージの処理方法が異なるため、以下に基づいてトレードオフを決定する必要があります。
  +  **メッセージ優先度:** メッセージブローカーは、通常のメッセージよりも先に優先度の高いメッセージを処理できます。イベントストリーミングでは、すべてのメッセージの優先度が同じになります。
  +  **メッセージ消費:** メッセージブローカーは、コンシューマーがメッセージを受信したかどうか確認します。イベントストリーミングのコンシューマーは、最後に読んだメッセージを常に把握しておく必要があります。
  +  **メッセージの順序:** メッセージングでは、先入れ先出し (FIFO) アプローチを使用しない限り、メッセージの送信順序を正確に受信することは保証されません。イベントストリーミングでは、データが生成された順序が常に保持されます。
  +  **メッセージの削除:** メッセージングでは、コンシューマーはメッセージを処理した後に削除する必要があります。イベントストリーミングサービスはメッセージをストリームに追加し、メッセージの保存期間が終了するまでストリームに残ります。この削除ポリシーにより、イベントストリーミングはメッセージの再生に適したものになります。
+  依存関係がいつ作業を完了したかをワークロードがどのように認識するかを定義します。ワークロードが [Lambda 関数を非同期的](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)に呼び出すと、Lambda はリクエストをキューに入れ、追加情報を含まない成功のレスポンスを返します。処理が完了すると、Lambda 関数は成功または失敗に基づいて設定可能な[送信先に結果を送信](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-destinations)できます。
+  べき等性を活用して、重複メッセージを処理するワークロードを構築します。べき等性とは、同じメッセージに対してワークロードが複数回生成されても、ワークロードの結果は変化しないことを指します。ネットワーク障害が発生した場合、または確認応答が受信されていない場合、[メッセージング](https://aws.amazon.com/sqs/faqs/#FIFO_queues)サービスまたは[ストリーミング](https://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-duplicates.html)サービスがメッセージを再配信することに注意してください。
+  ワークロードが依存関係から応答を受け取らない場合は、ワークロードはリクエストを再送信します。リトライ回数を制限して、ワークロードの CPU、メモリ、ネットワークリソースの消費を抑え、他のリクエストを処理できるようにすることを検討してください。「[AWS Lambda ドキュメント](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-errors)」では、非同期呼び出しのエラーを処理する方法を示しています。
+  適切なオブザーバビリティ、デバッグ、トレースツールを活用して、ワークロードの非同期通信とその依存関係を管理し運用します。[Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) を使用して、[メッセージング](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html)および[イベントストリーミング](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html)サービスをモニタリングできます。また、[AWS X-Ray](https://aws.amazon.com/xray/) を使用してワークロードを計測し、問題のトラブルシューティングに関する[インサイトをすばやく得る](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html)こともできます。

 **バッチ依存関係** 

 バッチシステムは、手動操作なしで、入力データを受け取り、処理するための一連のジョブを開始し、いくつかの出力データを生成します。データサイズにもよりますが、ジョブは数分から、場合によっては数日かかることもあります。ワークロードで依存関係とのバッチ通信を行う場合は、以下のガイダンスを検討します。
+  ワークロードでバッチジョブを実行する時間枠を定義します。ワークロードでは、例えば 1 時間ごとまたは月末に、バッチシステムを呼び出す繰り返しパターンを設定できます。
+  データ入力と処理済みデータ出力の場所を定義します。[Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/)、[Amazon Elastic File System (Amazon EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html)、[Amazon FSx for Lustre ](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html)などのストレージサービスを使用すると、大規模なワークロードのファイル読み書きに対応できます。
+  ワークロードで複数のバッチジョブを呼び出す必要がある場合は、[AWS Step Functions](https://aws.amazon.com/step-functions/?step-functions.sort-by=item.additionalFields.postDateTime&step-functions.sort-order=desc) を活用して、AWS またはオンプレミスで実行されるバッチジョブのオーケストレーションを簡素化できます。この[サンプルプロジェクト](https://github.com/aws-samples/aws-stepfunction-complex-orchestrator-app)は、Step Functions、[AWS Batch](https://aws.amazon.com/batch/)、および Lambda を使用したバッチジョブのオーケストレーションを示しています。
+  バッチジョブをモニタリングして、ジョブの完了に本来よりも時間がかかっているなどの異常がないかを確認します。[CloudWatch Container Insights](https://docs.aws.amazon.com/batch/latest/userguide/cloudwatch-container-insights.html) などのツールを使用して、AWS Batch 環境やジョブをモニタリングできます。この場合、ワークロードによって次のジョブの開始が停止し、関連するスタッフに例外が通知されます。

## リソース
<a name="resources"></a>

 **関連ドキュメント:** 
+  [AWS クラウド Operations: モニタリングとオブザーバビリティ](https://aws.amazon.com/cloudops/monitoring-and-observability) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [REL11-BP05 静的安定性を使用してバイモーダル動作を防止する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_withstand_component_failures_static_stability.html) 
+  [AWS Lambda デベロッパーガイド: AWS Lambda でのエラー処理と自動再試行](https://docs.aws.amazon.com/lambda/latest/dg/invocation-retries.html) 
+  [レイテンシーを考慮した Amazon DynamoDB アプリケーションのための AWS Java SDK HTTP リクエスト設定のチューニング](https://aws.amazon.com/blogs/database/tuning-aws-java-sdk-http-request-settings-for-latency-aware-amazon-dynamodb-applications/) 
+  [AWS メッセージング](https://aws.amazon.com/messaging/) 
+  [ストリーミングデータとは](https://aws.amazon.com/streaming-data/) 
+  [AWS Lambda デベロッパーガイド: 非同期呼び出し](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html) 
+  [Amazon Simple Queue Service に関するよくある質問: FIFO キュー](https://aws.amazon.com/sqs/faqs/#FIFO_queues) 
+  [Amazon Kinesis Data Streams デベロッパーガイド: 重複レコードの処理](https://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-duplicates.html) 
+  [Amazon Simple Queue Service デベロッパーガイド: Amazon SQS で使用できる CloudWatch メトリクス](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-available-cloudwatch-metrics.html) 
+  [Amazon Kinesis Data Streams デベロッパーガイド: Amazon CloudWatch による Amazon Kinesis Data Streams Service のモニタリング](https://docs.aws.amazon.com/streams/latest/dev/monitoring-with-cloudwatch.html) 
+  [AWS X-Ray デベロッパーガイド: AWS X-Rayの概念](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html) 
+  [GitHub の AWS サンプル: AWS Step Functions 複雑なオーケストレーターアプリ](https://github.com/aws-samples/aws-stepfunction-complex-orchestrator-app) 
+  [AWS Batch ユーザーガイド: AWS Batch CloudWatch Container Insights](https://docs.aws.amazon.com/batch/latest/userguide/cloudwatch-container-insights.html) 

 **関連動画:** 
+  [AWS Summit SF 2022 - AWS によるフルスタックのオブザーバビリティとアプリケーションモニタリング (COP310)](https://www.youtube.com/watch?v=or7uFFyHIX0) 

 **関連ツール**: 
+  [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) 
+  [Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html) () 
+  [AWS X-Ray](https://aws.amazon.com/xray/) 
+  [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) 
+  [Amazon Elastic File System (Amazon EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html) 
+  [Amazon FSx for Lustre](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html) 
+  [AWS Step Functions](https://aws.amazon.com/step-functions/?step-functions.sort-by=item.additionalFields.postDateTime&step-functions.sort-order=desc) 
+  [AWS Batch](https://aws.amazon.com/batch/) 

# REL04-BP02 疎結合の依存関係を実装する
<a name="rel_prevent_interaction_failure_loosely_coupled_system"></a>

 キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、疎結合されています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。

 キューイングシステム、ストリーミングシステム、ワークフローなどの依存関係を疎結合化すると、システムへの変更や障害の影響を最小限に抑えることができます。疎結合化により、コンポーネントの動作が依存する他のシステムに影響を与えないように分離され、回復力と俊敏性が向上します。

 密結合のシステムでは、あるコンポーネントを変更すると、そのコンポーネントに依存する他のコンポーネントも変更しなければならなくなり、結果として、すべてのコンポーネントのパフォーマンスが低下する可能性があります。疎結合はこの依存関係を壊すため、依存コンポーネントが知る必要があるのは、バージョン管理されて公開されたインターフェイスのみです。依存関係があるコンポーネント間に疎結合を実装すると、あるコンポーネントの障害が別のコンポーネントに影響を及ぼさないように隔離することができます。

 疎結合では、コードの変更やコンポーネントへの機能の追加を自由にできる一方で、そのコンポーネントに依存する他のコンポーネントへのリスクを最小限に抑えることができます。また、回復力を細分化でき、コンポーネントレベルでスケールアウトしたり、依存関係の根本的な実装さえも変更したりできます。

 疎結合によって弾力性をさらに向上させるには、可能な場合はコンポーネント間のやりとりを非同期にします。このモデルは、即時応答を必要とせず、リクエストが登録されていることの確認で十分な状況では、どのような対話にも最適です。イベントを生成するコンポーネントと、イベントを消費するコンポーネントがあります。2 つのコンポーネントは、直接的なポイントツーポイントのやりとりではなく、通常、Amazon SQS キューのような中間的な耐久性の高いストレージレイヤーや Amazon Kinesis のようなストリーミングデータプラットフォーム、または AWS Step Functions を介して統合されます。

![\[キューイングシステムやロードバランサーなどの依存関係が疎結合されていることを示す図\]](http://docs.aws.amazon.com/ja_jp/wellarchitected/latest/reliability-pillar/images/dependency-diagram.png)


 Amazon SQS キューと AWS Step Functions は、疎結合の中間レイヤーを追加する方法のうちの 2 つにすぎません。Amazon EventBridge を使用してイベント駆動型アーキテクチャを AWS クラウドに構築することもできます。Amazon EventBridge は、クライアント (イベントプロデューサー) が依存するサービス (イベントコンシューマー) から抽象化できます。Amazon Simple Notiﬁcation Service (Amazon SNS) は、高スループットのプッシュベースの多対多メッセージングが必要な場合に効果的なソリューションです。Amazon SNS トピックを使用すると、パブリッシャーシステムは、メッセージを多数のサブスクライバーエンドポイントにファンアウトして、並列処理できます。

 キューにはいくつかの利点がありますが、ほとんどのハードリアルタイムシステムでは、しきい値の時間 (多くの場合、数秒) よりも長時間かかっているリクエストは古くなっているとみなされ (クライアントが停止し、応答を待機しなくなる)、処理されません。このように、古くなったリクエストの代わりに、より新しい (そしておそらくまだ有効な) リクエストを処理することができます。

 **期待される成果:** 疎結合の依存関係を実装すると、コンポーネントレベルへの障害の面積を最小限に抑えることができ、問題の診断と解決に役立ちます。また、開発サイクルが簡素化され、チームはモジュールレベルで変更を実装できるようになり、その部分に依存する他のコンポーネントのパフォーマンスに影響は及びません。このアプローチでは、リソースのニーズに基づいてコンポーネントレベルでスケールアウトできるだけでなく、コスト効率良くコンポーネントを活用できるようになります。

 **一般的なアンチパターン:** 
+  モノリシックワークロードのデプロイ。
+  リクエストのフェイルオーバーや非同期処理を行うことはできない状態で、ワークロード層間で直接 API を呼び出す。
+  共有データを使用した密結合。疎結合のシステムでは、共有データベースや他の形で密結合されたデータストレージを介したデータの共有を避ける必要があります。そうしたデータ共有が密結合を持ち込み、スケーラビリティを妨げる可能性があります。
+  バックプレッシャーを無視する。ワークロードには、コンポーネントが同じ速度でデータを処理できない場合に、データの受信を遅らせたり停止したりする機能が必要です。

 **このベストプラクティスを活用するメリット:** 疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから隔離するのに役立ち、弾力性と俊敏性を高めます。1 つのコンポーネントの障害は他のコンポーネントから隔離されます。

 **このベストプラクティスを活用しない場合のリスクレベル:** 高 

## 実装のガイダンス
<a name="implementation-guidance"></a>

 疎結合の依存関係を実装します。疎結合のアプリケーションを構築するためのさまざまなソリューションがあります。フルマネージド型のキュー、自動化されたワークフロー、イベントへの対応、API などを実装するサービスがこれに当たりますが、いずれも、コンポーネントの動作を他のコンポーネントから隔離するのに役立ち、弾力性と俊敏性を高めます。
+  **イベント駆動型アーキテクチャの構築:** [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) は、疎結合で分散されたイベント駆動型アーキテクチャの構築に役立ちます。
+  **分散システムにキューを実装する:** [Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) を使用して、分散システムを統合および疎結合化できます。
+  **コンポーネントをマイクロサービスとしてコンテナ化:** [マイクロサービス](https://aws.amazon.com/microservices/)を使用すると、チームは十分に定義された API を通して通信する小型の独立コンポーネントから構成されるアプリケーションを構築できます。[Amazon Elastic Container Service (Amazon ECS)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) および [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html) は、コンテナ化をすばやく実現できます。
+  **Step Functions を使用してワークフローを管理する:** [Step Functions](https://aws.amazon.com/step-functions/getting-started/) は、複数の AWS サービスを柔軟なワークフローに調整するのに役立ちます。
+  **パブリッシュ/サブスクライブ (pub/sub) メッセージングアーキテクチャを活用する:** [Amazon Simple Notiﬁcation Service (Amazon SNS)](https://docs.aws.amazon.com/sns/latest/dg/welcome.html) は、パブリッシャーからサブスクライバー (プロデューサーおよびコンシューマーとも呼ばれます) へのメッセージ配信を提供します。

### 実装手順
<a name="implementation-steps"></a>
+  イベント駆動型アーキテクチャのコンポーネントは、イベントによって開始されます。イベントは、ユーザーがカートに商品を追加するなど、システム内で発生するアクションです。アクションが正常に実行されると、システムの次のコンポーネントを起動するイベントが生成されます。
  + [ Amazon EventBridge を使用したイベント駆動型アプリケーションの構築 ](https://aws.amazon.com/blogs/compute/building-an-event-driven-application-with-amazon-eventbridge/)
  + [AWS re:Invent 2022: Amazon EventBridge を使用したイベント駆動型統合の設計 ](https://www.youtube.com/watch?v=W3Rh70jG-LM)
+  分散型メッセージングシステムには、キューベースのアーキテクチャを確立するために主に 3 つの部分を実装する必要があります。これには、分散型システムのコンポーネント、分離のために使用するキュー (Amazon SQS サーバー上で分散される)、キュー内のメッセージが該当します。一般的なシステムには、キューへのメッセージ配信を開始するプロデューサーと、キューからメッセージを受信するコンシューマーがあります。キューは、冗長性を確保するために、複数の Amazon SQS サーバーにメッセージを格納します。
  + [ Amazon SQS の基本的なアーキテクチャ](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html)
  + [ Amazon Simple Queue Service を使用して分散アプリケーション間でメッセージを送信する ](https://aws.amazon.com/getting-started/hands-on/send-messages-distributed-applications/)
+  マイクロサービスをうまく利用すれば、疎結合のコンポーネントが独立したチームによって管理されるため、保守性とスケーラビリティが向上します。また、変更が必要になっても、動作を分離し、単一のコンポーネントに限定できます。
  + [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/microservices-on-aws.html)
  + [Let's Architect\$1 コンテナを使用するマイクロサービスの設計 ](https://aws.amazon.com/blogs/architecture/lets-architect-architecting-microservices-with-containers/)
+  AWS Step Functions では、分散型アプリケーションの構築、プロセスの自動化、マイクロサービスのオーケストレーションなどを行うことができます。複数のコンポーネントをオーケストレーションして 1 つのワークフローとしてまとめ、自動化することで、アプリケーション内の依存関係を分離できます。
  + [AWS Step Functions と AWS Lambda を使用してサーバーレスワークフローを作成する](https://aws.amazon.com/tutorials/create-a-serverless-workflow-step-functions-lambda/)
  + [AWS Step Functions の開始方法](https://aws.amazon.com/step-functions/getting-started/)

## リソース
<a name="resources"></a>

 **関連ドキュメント:** 
+  [Amazon EC2: べき等性を保証する](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [What Is Amazon EventBridge?](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html)
+  [Amazon Simple Queue Service とは](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 
+ [ モノリスから卒業する ](https://pages.awscloud.com/break-up-your-monolith.html)
+ [AWS Step Functions および Amazon SQS を使用してキューベースのマイクロサービスをオーケストレーションする ](https://aws.amazon.com/tutorials/orchestrate-microservices-with-message-queues-on-step-functions/)
+ [ Amazon SQS の基本的なアーキテクチャ ](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html)
+ [ キューベースのアーキテクチャ ](https://docs.aws.amazon.com/wellarchitected/latest/high-performance-computing-lens/queue-based-architecture.html)

 **関連動画:** 
+  [AWS New York Summit 2019: イベント駆動型アーキテクチャと Amazon EventBridge 入門 (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: イベント駆動型アーキテクチャへの移行 (SVS308)](https://youtu.be/h46IquqjF3E) 
+ [AWS re:Invent 2019: Amazon SQS と Lambda を使用するスケーラブルなサーバーレスイベント駆動型アプリケーション ](https://www.youtube.com/watch?v=2rikdPIFc_Q)
+ [AWS re:Invent 2022: Amazon EventBridge を使用したイベント駆動型統合の設計 ](https://www.youtube.com/watch?v=W3Rh70jG-LM)
+ [AWS re:Invent 2017: Elastic Load Balancing の詳細とベストプラクティス ](https://www.youtube.com/watch?v=9TwkMMogojY)

# REL04-BP03 継続動作を行う
<a name="rel_prevent_interaction_failure_constant_work"></a>

 負荷が急激に大きく変化すると、システム障害が発生することがあります。例えば、ワークロードで何千台ものサーバーのヘルスをモニタリングするヘルスチェックを実行する場合、毎回同じサイズのペイロード (現在の状態の完全なスナップショット) を送信しています。障害が発生しているサーバーがなくても、またはそのすべてに障害が発生していても、ヘルスチェックシステムは、大規模で急激な変更なしに常に作業を行っています。

 例えば、ヘルスチェックシステムが 100,000 台のサーバーをモニタリングしている場合、通常のサーバー障害率が軽いときは、その負荷はわずかです。しかし、重大なイベントによってこれらのサーバーの半分が異常な状態になると、ヘルスチェックシステムは、通知システムを更新し、クライアントに状態を通知しようとして過負荷になるでしょう。したがって、ヘルスチェックシステムは毎回現在の状態のフルスナップショットを送信する必要があります。それぞれがビットで表される 100,000 個のサーバーヘルス状態は、12.5 KB のペイロードにすぎません。サーバーに障害が発生していないか、またはすべてに発生しているかにかかわらず、ヘルスチェックシステムは定期的に作業を行っているため、大規模の急激な変化はシステムの安定性を脅かすものではありません。これは実際に Amazon Route 53 がエンドポイントのヘルスチェック (IP アドレスなど) によってエンドユーザーがどのようにルーティングされているかを調べる際の方法です。

 **このベストプラクティスを活用しない場合のリスクレベル:** 低 

## 実装のガイダンス
<a name="implementation-guidance"></a>
+  負荷が急激に変化してシステム障害が発生しないように、継続動作を行います。
+  疎結合の依存関係を実装します。キューイングシステム、ストリーミングシステム、ワークフロー、ロードバランサーなどの依存関係は、疎結合されています。疎結合は、コンポーネントの動作をそれに依存する他のコンポーネントから分離するのに役立ち、弾力性と俊敏性を高めます。
  +  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
  +  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (継続動作を含む)](https://youtu.be/O8xLxNje30M?t=2482) 
    +  100,000 台のサーバーをモニタリングするヘルスチェックシステムの例の場合、成功または失敗の数に関係なく、ペイロードサイズが一定になるように、ワークロードを設計します。

## リソース
<a name="resources"></a>

 **関連ドキュメント:** 
+  [Amazon EC2: べき等性を保証する](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **関連動画:** 
+  [AWS New York Summit 2019: イベント駆動型アーキテクチャと Amazon EventBridge 入門 (MAD205)](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (継続動作を含む)](https://youtu.be/O8xLxNje30M?t=2482) 
+  [AWS re:Invent 2018: ループを閉じ、発想を開く: 大小さまざまなシステムをコントロールする方法 ARC337 (疎結合、継続動作、静的安定性を含む)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019: イベント駆動型アーキテクチャへの移行 (SVS308)](https://youtu.be/h46IquqjF3E) 

# REL04-BP04 変更操作をべき等にする
<a name="rel_prevent_interaction_failure_idempotent"></a>

 べき等性のサービスは、各リクエストが 1 回だけ処理することを約束します。そのため、同一のリクエストを複数回行っても、リクエストを 1 回行ったのと同じ効果しかありません。これにより、リクエストが誤って複数回処理されることを恐れる必要がなくなるため、クライアントが再試行しやすくなります。これを行うには、クライアントは、リクエストが繰り返されるたびに使用されるべき等性トークンを使用して API リクエストを発行できます。べき等性サービス API は、システムの基盤となる状態が変更された場合でも、トークンを使用してリクエストが最初に完了したときに返された応答と同じ応答を返します。

 分散システムでは、アクションを最大で 1 回 (クライアントがリクエストを 1 回だけ行う)、または少なくとも 1 回 (クライアントが成功を確認するまでリクエストを続ける) 実行するのは比較的簡単です。同一のリクエストを複数回行っても、リクエストを 1 回行ったのと同じ効果を持つように、アクションが*確実に 1 回*実行されることを保証するのはより困難です。API でべき等性トークンを使用すると、サービスは、重複レコードや副作用を生むことなく、変更リクエストを 1 回または複数回受け取ることができます。

 **期待される成果:** すべてのコンポーネントとサービスにわたってべき等性を保証するための、一貫性があり、十分に文書化され、広く採用されているアプローチが得られます。

 **一般的なアンチパターン:** 
+  必要でない場合でも、無差別にべき等性を適用している。
+  べき等性を実装するための過度に複雑なロジックを導入している。
+  タイムスタンプは、べき等性のキーとして使用している。これにより、クロックスキューや、複数のクライアントが同じタイムスタンプを使用して変更を適用することが原因で、不正確さが生じる可能性があります。
+  べき等性を保つためにペイロード全体を保存している。このアプローチでは、リクエストごとに完全なデータペイロードを保存し、新しいリクエストごとに上書きします。これにより、パフォーマンスが低下し、スケーラビリティに影響する可能性があります。
+  サービス間でキーの生成に一貫性がない。一貫したキーがないと、サービスは重複するリクエストを認識しない可能性があり、意図しない結果になる可能性があります。

 **このベストプラクティスを活用するメリット:** 
+  スケーラビリティの向上: システムは、追加のロジックや複雑な状態管理を実行することなく、再試行や重複したリクエストを処理できます。
+  信頼性の向上: べき等性により、サービスは複数の同一リクエストを一貫した方法で処理できるようになり、予期しない副作用や重複レコードのリスクが軽減されます。これは、ネットワーク障害や再試行が頻繁に発生する分散システムでは特に重要です。
+  データ整合性の向上: 同じリクエストが同じレスポンスを生成するため、べき等性は分散システム間でデータ整合性を維持するのに役立ちます。これは、トランザクションとオペレーションの整合性を維持するために不可欠です。
+  エラー処理: べき等性トークンを使用すると、エラー処理がより簡単になります。問題によりクライアントが応答を受信しなかった場合、同じべき等性トークンを使用してリクエストを安全に再送信できます。
+  運用上の透明性: べき等性を使用すると、モニタリングとログ記録が向上します。サービスは、べき等性トークンを使用してリクエストをログに記録できるため、問題の追跡とデバッグが容易になります。
+  API 契約の簡素化: クライアント側とサーバー側のシステム間の契約を簡素化し、誤ったデータ処理が行われる恐れを軽減します。

 **このベストプラクティスを活用しない場合のリスクレベル:** 中 

## 実装のガイダンス
<a name="implementation-guidance"></a>

 分散システムでは、アクションを最大 1 回 (クライアントは 1 つのリクエストのみを行う) または少なくとも 1 回 (クライアントは成功が確認されるまでリクエストを続ける) 実行するのは比較的簡単です。ただし、*確実に 1 回だけ*動作を実装するのは困難です。これを実現するには、クライアントはリクエストごとにべき等性トークンを生成して提供する必要があります。

 べき等性トークンを使用することによって、サービスは新しいリクエストと繰り返しのリクエストを区別できます。サービスがべき等性トークンを含むリクエストを受信すると、そのトークンが既に使用されているかどうかが確認されます。トークンが使用されている場合、サービスは保存されたレスポンスを取得して返します。トークンが新しい場合、サービスはリクエストを処理し、レスポンスをトークンと共に保存し、レスポンスを返します。このメカニズムにより、すべてのレスポンスがべき等になり、分散システムの信頼性と一貫性が向上します。

 べき等性は、イベント駆動型アーキテクチャの重要な動作でもあります。これらのアーキテクチャは通常、Amazon SQS、Amazon MQ、Amazon Kinesis Streams、Amazon Managed Streaming for Apache Kafka (MSK) などのメッセージキューによってサポートされます。状況によっては、1 回だけ公開されたメッセージが誤って複数回配信されることがあります。パブリッシャーがべき等性トークンを生成してメッセージに含める場合、受信した重複メッセージの処理によって、同じメッセージに対するアクションが繰り返されないように要求します。コンシューマーは受信した各トークンを追跡し、重複したトークンを含むメッセージを無視する必要があります。

 サービスとコンシューマーは、受信したべき等性トークンを、呼び出すダウンストリームサービスにも渡す必要があります。同様に、処理チェーン内のすべてのダウンストリームサービスは、メッセージを複数回処理することの副作用を避けるために、べき等性が実装されていることを確認する責任があります。

### 実装手順
<a name="implementation-steps"></a>

1.  **べき等性オペレーションを特定する** 

    どのオペレーションにべき等性が必要かを判断します。通常、これには POST、PUT、DELETE HTTP メソッドとデータベースの挿入、更新、または削除オペレーションが含まれます。読み取り専用クエリなど、状態を変更しない操作では、副作用がない限り、通常はべき等性は必要ありません。

1.  **一意の識別子を使用する** 

    送信者から送信される各べき等オペレーションのリクエストには、リクエストに直接、またはメタデータ (HTTP ヘッダーなど) の一部として、一意のトークンを含めます。これにより、受信者は重複するリクエストやオペレーションを認識して処理できます。トークンに一般的に使用される識別子には、[Universally Unique Identifiers (UUID)](https://datatracker.ietf.org/doc/html/rfc9562) と [K-Sortable Unique Identifiers (KSUID)](https://github.com/segmentio/ksuid) があります。

1.  **状態の追跡と管理** 

    ワークロード内の各オペレーションまたはリクエストの状態を維持します。これは、べき等性トークンと対応する状態 (保留中、完了、失敗など) をデータベース、キャッシュ、またはその他の永続的ストアに保存することによって実現できます。この状態情報により、ワークロードは重複するリクエストやオペレーションを識別して処理できます。

    必要に応じて、ロック、トランザクション、オプティミスティック同時実行コントロールなどの適切な同時実行コントロールメカニズムを使用して、一貫性と原子性を維持します。これには、べき等性トークンを記録し、リクエストの処理に関連するすべての変更操作を実行するプロセスが含まれます。これにより、競合状態を防ぎ、べき等操作が正しく実行されることを確認できます。

    ストレージとパフォーマンスを管理するために、データストアから古いべき等性トークンを定期的に削除します。ストレージシステムがサポートしている場合は、データの有効期限タイムスタンプ (有効期限または TTL 値とも呼ばれます) の使用を検討してください。べき等性トークンの再利用の可能性は時間の経過と共に減少します。

    べき等性トークンと関連する状態を保存するために通常使用される一般的な AWS ストレージオプションは次のとおりです。
   +  **Amazon DynamoDB**: DynamoDB は、低レイテンシーのパフォーマンスと高可用性を提供する NoSQL データベースサービスであり、べき等性関連データの保存に最適です。DynamoDB のキー値およびドキュメントデータモデルにより、べき等性トークンと関連する状態情報を効率的に保存および取得できます。また、アプリケーションが挿入時に TTL 値を設定すると、DynamoDB はべき等性トークンを自動的に期限切れにすることもできます。
   +  **Amazon ElastiCache**: ElastiCache は、高スループット、低レイテンシー、低コストでべき等性トークンを保存できます。ElastiCache (Redis) と ElastiCache (Memcached) の両方とも、アプリケーションが挿入時に TTL 値を設定すると、べき等性トークンを自動的に期限切れにすることもできます。
   +  **Amazon Relational Database Service (RDS):** 特にアプリケーションが他の目的でリレーショナルデータベースを既に使用している場合は、Amazon RDS を使用してべき等性トークンと関連する状態情報を保存できます。
   +  **Amazon Simple Storage Service (S3):** Amazon S3 は、べき等性トークンと関連メタデータの保存に使用できる、スケーラビリティと耐久性の高いオブジェクトストレージサービスです。S3 のバージョニング機能は、べき等操作の状態を維持するのに特に役立ちます。ストレージサービスの選択は、通常、べき等性関連データの量、必要なパフォーマンス特性、耐久性と可用性の必要性、べき等性メカニズムが全体的なワークロードアーキテクチャとどのように統合されるかなどの要因によって決まります。

1.  **べき等性オペレーションを実装する** 

    API とワークロードコンポーネントをべき等になるように設計します。べき等性チェックをワークロードコンポーネントに組み込みます。リクエストを処理する前、またはオペレーションを実行する前に、一意の識別子が既に処理されているかどうかを確認します。存在する場合は、オペレーションを再度実行する代わりに、前の結果を返します。例えば、クライアントがユーザーの作成リクエストを送信した場合、同じ一意の識別子を持つユーザーが既に存在するかどうかを確認します。ユーザーが存在する場合は、新しいユーザー情報を作成する代わりに、既存のユーザー情報を返す必要があります。同様に、キューコンシューマーが重複したべき等性トークンを含むメッセージを受信した場合、コンシューマーはそのメッセージを無視する必要があります。

    リクエストのべき等性を検証する包括的なテストスイートを作成します。成功したリクエスト、失敗したリクエスト、重複したリクエストなど、幅広いシナリオをカバーする必要があります。

    ワークロードが AWS Lambda 関数を活用する場合は、AWS Lambda の Powertools を検討してください。Powertools for AWS Lambda は、サーバーレスのベストプラクティスを実装し、AWS Lambda 関数を操作する際のデベロッパーの速度を向上させるデベロッパーツールキットです。特に、Lambda 関数を再試行しても安全なべき等操作に変換するユーティリティを提供します。

1.  **べき等性を明確に伝える** 

    API とワークロードコンポーネントをドキュメント化して、操作のべき等性を明確に伝えます。これにより、クライアントは予想される動作と、ワークロードと確実にやり取りする方法を理解できます。

1.  **モニタリングと監査** 

    モニタリングと監査のメカニズムを実装して、予期しないレスポンスの変動や過剰な重複リクエストの処理など、レスポンスのべき等性に関連する問題を検出します。これにより、ワークロードの問題や予期しない動作を検出して調査できます。

## リソース
<a name="resources"></a>

 **関連するベストプラクティス:** 
+  [REL05-BP03 再試行呼び出しを制御および制限する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_mitigate_interaction_failure_limit_retries.html) 
+  [REL06-BP01 ワークロードのすべてのコンポーネントをモニタリングする (生成)](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_monitor_resources.html) 
+  [REL06-BP03 通知を送信する (リアルタイム処理とアラーム)](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_monitor_aws_resources_notification_monitor.html) 
+  [REL08-BP02 デプロイの一部として機能テストを統合する](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/rel_tracking_change_management_functional_testing.html) 

 **関連ドキュメント:** 
+  [The Amazon Builders' Library: Making retries safe with idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) 
+  [Amazon Builders' Library: 分散システムの課題](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library: 信頼性、動作の継続、1 杯のおいしいコーヒー](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [Amazon Elastic Container Service: Ensuring idempotency](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/ECS_Idempotency.html) 
+  [Lambda 関数をべき等にするにはどうすればよいですか?](https://repost.aws/knowledge-center/lambda-function-idempotent)
+  [Ensuring idempotency in Amazon EC2 API requests](https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html) 

 **関連動画:** 
+  [Building Distributed Applications with Event-driven Architecture - AWS Online Tech Talks](https://www.youtube.com/watch?v=gA2-eqDVSng&t=1668s) 
+  [AWS re:Invent 2023 - Building next-generation applications with event-driven architecture](https://www.youtube.com/watch?v=KXR17uwLEC8) 
+  [AWS re:Invent 2023 - Advanced integration patterns & trade-offs for loosely coupled systems](https://www.youtube.com/watch?v=FGKGdUiZKto) 
+  [AWS re:Invent 2023 - Advanced event-driven patterns with Amazon EventBridge ](https://www.youtube.com/watch?v=6X4lSPkn4ps) 
+  [AWS re:Invent 2018 - Close Loops and Opening Minds: How to Take Control of Systems, Big and Small ARC337 (includes loose coupling, constant work, static stability)](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019 - Moving to event-driven architectures (SVS308)](https://youtu.be/h46IquqjF3E) 

 **関連ツール**: 
+  [Idempotency with AWS Lambda Powertools (Java)](https://docs.powertools.aws.dev/lambda/java/utilities/idempotency/) 
+  [Idempotency with AWS Lambda Powertools (Python)](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/) 
+  [AWS Lambda Powertools GitHub page](https://github.com/aws-powertools/) 