Amazon SQS で構築する非同期メッセージング - Standard と FIFO キューの設計

Standard と FIFO キューの使い分け、DLQ による処理失敗メッセージの退避、Lambda イベントソースマッピングによる自動処理を紹介します。

SQS の概要

SQS はフルマネージドのメッセージキューイングサービスです。SNS が 1 対多のファンアウトを提供するのに対し、SQS は 1 対 1 のポイントツーポイントメッセージングを提供します。Web アプリケーションのリクエスト処理とバックエンドの重い処理を分離し、スケーラビリティと耐障害性を向上させます。SQS はメッセージを複数の AZ に冗長保存するため、単一 AZ の障害でメッセージが消失することはありません。メッセージの保持期間はデフォルト 4 日間で、最大 14 日間まで延長可能です。Visibility Timeout はデフォルト 30 秒で、コンシューマが処理中のメッセージを他のコンシューマが受信しないよう制御します。

キュー設計と DLQ

Standard キューは秒間数万メッセージのスループットを提供し、メッセージの順序は保証されません (ベストエフォート順序)。少なくとも 1 回の配信 (at-least-once) を保証するため、コンシューマ側で冪等性を確保する設計が必要です。FIFO キューはメッセージグループ ID ごとに順序を保証し、重複排除 ID で exactly-once 処理を実現します。スループットは秒間 300 メッセージ (バッチで 3000)、高スループットモード有効時は秒間数千メッセージまで拡張できます。DLQ は maxReceiveCount 回処理に失敗したメッセージを自動的に移動し、メインキューの処理を妨げません。DLQ のメッセージを調査し、原因を修正した後にメインキューに再ドライブ (再送) できます。DLQ の保持期間はソースキューと独立して設定できるため、調査に十分な期間 (例: 14 日) を設定することが推奨されます。

Lambda 統合と大容量メッセージ

SQSLambda のイベントソースマッピングで、キューのメッセージを自動的に Lambda 関数で処理します。バッチサイズ (最大 10,000) とバッチウィンドウ (最大 300 秒) を設定し、複数メッセージをまとめて処理することで Lambda の呼び出し回数を削減します。部分バッチ応答 (ReportBatchItemFailures) を有効にすると、バッチ内の失敗メッセージのみを再処理でき、成功メッセージの重複処理を回避できます。FIFO キューでは Lambda の同時実行数がメッセージグループ数に制限されます。Extended Client Library で 256 KB を超えるメッセージを S3 経由で送受信し、大容量データの非同期処理に対応します。メッセージの暗号化は SSE-SQS (無料) または SSE-KMS で設定します。 メッセージキューに関する詳しい解説はAmazon の関連書籍でも確認できます。

設計のベストプラクティスと落とし穴

Visibility Timeout はコンシューマの最大処理時間よりも長く設定します。短すぎるとメッセージが再配信され重複処理の原因になります。Standard キューではコンシューマの冪等性が必須です。DynamoDB の条件付き書き込みやデータベースの一意制約で重複処理を防ぎます。FIFO キューの重複排除ウィンドウは 5 分間固定であり、5 分以内に同じ重複排除 ID でメッセージを送信すると後続が破棄されます。ロングポーリング (WaitTimeSeconds を 1〜20 秒に設定) は必ず有効にしてください。ショートポーリングでは空レスポンスが頻発し、無駄なリクエスト課金が発生します。メッセージ属性 (MessageAttributes) をルーティングやフィルタリングに活用し、メッセージ本文のパースを最小限に抑えることでコンシューマのパフォーマンスが向上します。

SQS の料金と制限の注意点

SQS の Standard キューは 100 万リクエストあたり約 0.40 ドル、FIFO キューは約 0.50 ドルです。最初の 100 万リクエスト/月は無料です。1 リクエストは最大 256 KB で、64 KB チャンクごとに 1 リクエストとしてカウントされます。ロングポーリング (WaitTimeSeconds=20) で空のレスポンスを削減し、リクエスト数を最適化します。DLQ のメッセージは通常のキューと同じ料金で課金されるため、DLQ のメッセージを定期的に処理または削除します。インフライトメッセージ数は Standard で 120,000、FIFO で 20,000 が上限です。この上限を超えると OverLimit エラーが返るため、コンシューマのスケーリングで処理速度を確保する設計が重要です。SSE-KMS 暗号化を使用する場合、KMS API 呼び出しに追加費用が発生します。大量メッセージを処理するキューでは SSE-SQS (追加費用なし) の利用を検討してください。

SQS と他のメッセージングサービスの比較

SQS はプルベースのポイントツーポイント型キューです。SNS はプッシュベースのパブサブ型で、1 つのメッセージを複数のサブスクライバに同時配信します。SNS + SQS のファンアウトパターンでは、SNS トピックに複数の SQS キューをサブスクライブし、各キューで独立した処理を並行実行できます。Amazon MQ は Apache ActiveMQ や RabbitMQ のマネージド版で、JMS や AMQP など既存プロトコルとの互換性が必要な場合に選択します。EventBridge はイベント駆動アーキテクチャ向けで、100 以上の AWS サービスと SaaS からのイベントをルールベースでルーティングします。SQS は大量メッセージのバッファリングとワーカーパターンに最適化されており、コスト効率と運用のシンプルさで優れています。

まとめ

SQS は非同期メッセージングで疎結合なアーキテクチャを構築するサービスです。Standard キューで秒間数万メッセージのスループットを提供し、FIFO キューで順序保証と重複排除を実現します。Lambda のイベントソースマッピングでメッセージを自動処理し、DLQ で処理失敗メッセージを退避させます。ロングポーリングでリクエスト数を最適化し、Extended Client Library で 256 KB 超のメッセージにも対応します。冪等性の確保と Visibility Timeout の適切な設定が、本番運用の安定性を左右する重要な設計ポイントです。