はじめに
私は、社会人になってから大量のデータに対するバッチ処理や、データ更新時のイベント処理などに触れる中で、メッセージキューを使ったシステム設計に興味を持つようになりました。 業務の中でSQSを使ったメッセージングの設計を行う機会もあり、ある程度理解しているつもりではありますが、あらためて言語化することで自分の理解を整理し、さらに深めることを目的に本記事にまとめてみました。
メッセージキューについて
SQSの説明に入る前に、まずメッセージキューについて軽く説明します。

メッセージキューとは、アプリケーション間でデータを非同期にやり取りする仕組みです。
- 送信側(Producer)がメッセージを作成し、メッセージをキューに送信します。
- メッセージブローカーは、メッセージをキューに格納、管理します。
- 受信側(Consumer)がキューからメッセージを取得し、処理します。処理が完了するとメッセージはキューから削除されます。
このような仕組みにより、大量のデータを扱うバッチ処理でも安定して実行できます。
また、一時的に負荷が増大してもキューが緩衝材となり、負荷を平準化しながら処理ができます。
さらに、障害が発生して処理が止まった場合でもメッセージが残るため、復旧後にリカバリしやすい点も大きなメリットです。
SQSについて
SQS (Amazon Simple Queue Service)は、AWSのメッセージングキューサービスです。
Queueの種類
SQSのQueueには、標準(Standard)キューとFIFOキューがあります。
標準キュー(standard Queue)
1秒あたりほぼ無制限の数のAPIコールを処理できる高スループットなキューである。
一方で、標準キューでは少なくとも一回(At-least-once)のメッセージ配信が保証されているため、同じメッセージが複数回配信される可能性がある。
また、分散性の高いアーキテクチャの特性上、メッセージが順不同で届くこともある。
そのため、アプリケーション側で冪等性を考慮したメッセージの設計が必要。
参考:AWS「Amazon SQS の標準キュー」 https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html
FIFOキュー(FIFO Queue)
FIFOキューは、メッセージを送信した順序どおりに処理できるキューであり、順序保証が必要な処理に適している。
また、FIFOキューでは重複排除機能により、同じメッセージが複数回配信されることを防ぐことができ、1回だけ処理されることを重視する用途に向いている。
一方で、標準キューと比べるとスループットには制限があり、大量処理を最優先したいケースでは注意が必要である。
参考:AWS「Amazon SQS の FIFO キュー」 https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html
Queueの特徴まとめ
| 項目 | 標準(Standard)Queue | FIFO Queue |
|---|---|---|
| 配信保証 | At-least-once(最低一回は届く) | Exactly-once processing(重複排除込みで実質1回) |
| スループット | 非常に高い(ほぼ制限なし) | 制限あり(Standardより低い) |
| メッセージ順序 | 保証しない | 保証する(送信順に処理される) |
| 重複配信 | 可能性あり | 基本的になし(重複排除できる) |
Queueの設定値
可視性タイムアウト(Visibility timeout)
コンシューマがメッセージを受信した後、一定時間そのメッセージを他のコンシューマから見えなくする仕組み。 処理中のメッセージが、他のワーカーにすぐ取得されて2重処理されることを防ぐ。
デフォルトは、30秒が設定されている。 0秒 ~ 12時間まで設定することができる。
また、ChangeMessageVisibilityを使用することで、キュー全体の設定を変更せず、個別のメッセージに特定の可視性タイムアウト(Visibility timeout)を延長、短縮することができる。
参考:AWS「Amazon SQS の可視性タイムアウト」 https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
メッセージの保持期間(Message retention period)
キューに残っているメッセージをSQSが保持する期間を設定できる。
デフォルトは4日が設定されており、1分から14日まで設定できる。
配信の遅延(Delivery delay)
キューに追加されたメッセージを配信する前に、SQSが遅延する時間を設定することができる。 デフォルトは0秒が設定されており、0秒から15分まで設定できる。
標準キューは、設定を変更しても既にキューにあるメッセージの遅延には影響されない。
一方、FIFOキューは、既にキューにあるメッセージの遅延に影響する。
参考:AWS「Amazon SQS の遅延キュー (Delay Queues)」 https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html
メッセージの最大サイズ(Maximum message size)
キューの最大メッセージサイズを設定できる。 デフォルト値は1024KiBが設定されており、1KiBから1024KiBで設定でできる。
参考:AWS「Amazon SQS の最大メッセージペイロードサイズが 1 MiB に増加」
※1024KiBを超えるメッセージを送信したい場合、S3を使用して対応することが可能のようです。
ここは別途検証をしようと考えています。
参考:AWS「Java と Amazon S3 を使用した大量の Amazon SQS メッセージの管理」
メッセージの受信待ち時間(Receive message wait timeout)
受信メッセージ待機時間は、ポーリングがメッセージが受信可能になるまで待機する時間を設定できます。
デフォルトは0秒が設定されており、0秒から20秒まで設定できます。
参考:AWS「Amazon SQSショートポーリングとロングポーリング」
Redrive allow policy
SQSで DLQ(Dead Letter Queue)に入ったメッセージを、元のキューや別のキューに戻す(redrive)操作を「どのキューから許可するか」制御する設定です。
許可する場合、「Allow all」「By queue」「Deny All」の三つがある。
-
Allow all どのキューからでも、このDeadLetterQueueのメッセージをredriveできる
-
By queue 指定したキューだけが、このDeadLetterQueueのメッセージをredriveできる
-
Deny all どのキューからも、このDeadLetterQueueのメッセージをredriveできない
Dead-letter queue
何度も処理に失敗するメッセージを隔離するためのキューです。
最大受信回数(Maximum receives)は、同じメッセージが何回ReceiveMessageされたらDeadLetterQueueに送るかを決めるパラメータです。
デフォルト値は10で、1から1000の間で設定できます。
まとめ
今回は、メッセージキューの基本的な仕組みと、SQSの概要について整理しました。
キューの種類(Standard/FIFO)や主要的な設定項目は、SQSの作成時に重要になります。
今後は、SQSを使った他のサービスとの連携やメッセージの設計について整理していこうと思います。