DVA-C02:AWS Certified Developer - Associate AWS サービスを用いた開発 問2
AWS サービスを用いた開発/AWS でホストされるアプリのコード開発Amazon SQS の標準キューからメッセージを受信するコンシューマーで、同一メッセージが複数回配信されても二重処理にならないようにしたいと考えています。最も適切な設計はどれですか。
当サイトのオリジナル問題(DVA-C02:AWS Certified Developer - Associateの出題範囲「AWS サービスを用いた開発」に対応。実際の試験問題ではありません)
- A可視性タイムアウトを 0 に設定する
- B処理を冪等(idempotent)に設計し、メッセージ ID や業務上の一意キーで重複を検知して重複分をスキップする
- Cメッセージを受信したら処理の前に即座に削除する
- D標準キューでは重複配信は起きないので対策は不要と考える
正解:B
解説
Amazon SQS の標準キューは、高いスループットと引き換えに「少なくとも1回(at-least-once)」の配信を提供し、まれに同一メッセージが複数回届くことがあります。そのため、コンシューマー側の処理を冪等(同じメッセージを複数回処理しても結果が変わらない)に設計し、一意キーで重複を検知してスキップするのが定石です。ここで注意が要るのは、「処理済みかを確認してから処理し、最後に記録する」という素朴な手順は原子的ではなく、複数コンシューマーの同時実行や処理途中の障害により、確認と記録の間で二重処理が起こり得る点です。重複管理は、キーの一意制約や条件付き書き込み(DynamoDB の条件付き Put など)で原子的に行い、処理の副作用(DB更新など)と処理済み記録をできる限り同一トランザクションで確定させて整合させます。また、重複判定のキーには SQS の MessageId だけでなく業務上の一意キー(注文番号など)を使うのが安全です。生産者が同じ業務イベントを再送すると別の MessageId が付与されるため、MessageId だけでは業務レベルの重複を取りこぼすことがあります。
下線の用語は 用語集 で意味を確認できます。
選択肢ごとの解説
- A誤り。可視性タイムアウトを 0 にすると、処理中のメッセージが他のコンシューマーにも配信され、重複処理がむしろ増えます。
- B正しい。処理を冪等に設計し、一意キーで重複を検知してスキップすれば、複数回配信されても二重処理になりません。ただし確認と記録は条件付き書き込みなどで原子的に行い、副作用と処理済み記録を整合させる必要があります。生産者の再送では MessageId が変わるため、重複判定には業務上の一意キーを用いるのが安全です。
- C誤り。処理前に削除すると、処理に失敗したときにメッセージが失われます。
- D誤り。標準キューは少なくとも1回の配信で重複が起こり得るため、対策は必要です。