NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

【20周年前祝い】歴史・年表でみるAWSサービス(Amazon Simple Queue Service編) -機能一覧・概要・アップデートのまとめ・Amazon SQS入門-

小西秀和です。
歴史・年表でみるAWS全サービス一覧 -アナウンス日、General Availability(GA)、AWSサービス概要のまとめ-」から始まった、AWSサービスを歴史・年表から機能を洗い出してまとめるシリーズの第7弾です(過去、Amazon S3AWS Systems ManagerAmazon Route 53Amazon EventBridgeAWS KMSについて書きました)。

今回は2004年11月にAWSインフラストラクチャサービスとして最初にアナウンスされ、フルマネージド型メッセージキューイングサービスを提供するAmazon Simple Queue Service(Amazon SQS)について歴史年表を作成してみました。
今年2024年11月にはAmazon SQSがアナウンスから20周年を迎えるということで、かなり早めではありますが前祝いという意味も含めて、この記事を書きました。
今回もAmazon SQSの誕生から機能追加やアップデートを追いながら主要機能を現在のAmazon SQSの機能一覧と概要としてまとめています。
これらが、各AWSサービスの機能概要に加えてコンセプトや変わらないもの、変わってきたものを知る手がかりとなればと考えています。
今回の記事の内容は次のような構成になっています。

Amazon SQS歴史年表の作成経緯と方法

今回、Amazon SQSの歴史年表を作成したのは、今年2024年にAmazon SQSがアナウンスから20周年を迎えることに他なりません。
Amazon SQSは2004年11月にAWSインフラストラクチャサービスとしてアナウンスされた最初のAWSサービスです(※1)。
そのため、2024年はAWSインフラストラクチャサービスがアナウンスされてから20周年という記念すべき年でもあります。

また、Amazon SQSが2004年11月に最初のAWSインフラストラクチャサービスとして登場して以降、ITトレンドが変化しても分散システム、マイクロサービス、サーバーレスアプリケーションなどで使用され続けるフルマネージド型メッセージキューイングサービスを提供してきたため、次のアプローチでAmazon SQSの情報を整理したいと考えたことも理由の一つです。

  • Amazon SQSの歴史を追いながら、アップデートの変遷を整理する
  • Amazon SQSの機能一覧と特徴をまとめる

この年表は主に次のブログやドキュメント履歴のAmazon SQSに関する内容を参考にしています。

年表の日付は、参考にした資料によってアナウンスや記事投稿のタイミングが違う場合もあったため、若干のブレがあります。
掲載している内容は現在のAmazon SQSと関係している主要な機能と概要説明に必要なものに限定しています。
つまり、ここの年表にあるものがAmazon SQSの機能のアップデートの全てではなく、あくまで私がピックアップした代表的なアップデートであることにご注意ください

※1) Introducing the Amazon Simple Queue Service参照。
インフラストラクチャサービス以外では「Alexa Web Information Service(AWIS)」というサービスがAmazon SQSより以前の2004-10-04に「What's New | 2004」へ記載されています。
また、最初にGeneral Availability(GA)となったのはAmazon Simple Storage Service(Amazon S3)で2006-03-14にアナウンスおよびGAとなりました。

Amazon SQS歴史年表(2004年11月03日~2024年05月01日までのアップデート)

さて、ここからがAmazon SQSの機能に関する年表です。Amazon SQSの歴史は本記事執筆時点で19年6ヶ月程度になり、2024年11月に20周年を迎えます。

※テーブルは項目名クリックでソートできます。

年月日 概要
2004/11/03 Amazon Simple Queue Service(Amazon SQS)がアナウンスされる。
2006/07/11 Amazon Simple Queue Service(Amazon SQS)がGeneral Availability(GA)になる。
2011/10/06 AWS Management ConsoleにAmazon SQSのサポートが追加される。
2011/10/21 Delay Queues、Message Timers、Batch APIsがサポートされる。
2012/11/05 Amazon SQSのAPIバージョン2012-11-05が発表。
2012/11/08 ロングポーリングがサポートされる。
2012/11/21 AWS Management Console for Amazon SQSを使用してAmazon SQSキューをAmazon SNSトピックにサブスクライブできるようになる。
2013/06/18 最大許容ペイロードサイズが64KBから256KBに増加される。
2014/01/29 デッドレターキューがサポートされる。
2014/05/06 メッセージ属性がサポートされる。
2014/07/16 AWS CloudTrailでAmazon SQSのAPIアクションをログに記録できるようになる。
2014/12/08 PurgeQueue APIアクションを使用してキュー内のメッセージを削除できるようになる。
2014/12/29 Amazon SQS Java Messaging Library for JMSが使用できるようになる。
2015/10/27 Amazon S3を使って最大2GBのペイロードを持つメッセージを送受信できるようになるAmazon SQS Extended Client Library for Javaが利用可能になる。
2016/03/30 Amazon CloudWatch EventsサービスでAmazon SQSキューをイベントターゲットとしてサポートするようになる。
2016/08/31 ApproximateAgeOfOldestMessage CloudWatchメトリックでキュー内の最も古いメッセージの経過時間を監視できるようになる。
2016/11/17 FIFO(先入れ先出し)キューが利用可能になり、既存のキューの新名称がスタンダードキューとなる。
2017/04/24 Amazon SQS Extended Client Library for JavaとAmazon SQS Java Messaging Library for JMSがFIFOキューをサポート。
2017/04/28 サーバーサイド暗号化(SSE)をサポート。
2017/05/01 Amazon SQSがHIPAA適格サービスとなる。
2017/05/19 Amazon SQS Extended Client Library for JavaをAmazon SQS Java Messaging Library for JMSとともに使用できるようになる。
2017/10/19 Amazon SQSキューでタグが使用できるようになり、コスト配分タグでコスト割り当てを追跡できるようになる。
2017/12/07 ListQueuesを除く全APIアクションがリソースレベルの権限をサポート。
2018/04/10 Amazon CloudWatch EventsサービスでAmazon SQS FIFOキューをイベントターゲットとしてサポートするようになる。
2018/06/28 AWS LambdaでAmazon SQS スタンダードキューをイベントソースとしてサポートするようになる。
2018/12/13 AWS PrivateLinkを使用したAmazon VPC Endpointsをサポートし、VPCをサポートするAWSサービスにプライベート接続できるようになる。
2019/04/04 VPCエンドポイントポリシーをサポート。
2019/07/25 一時キュークライアントが利用可能になる。
2019/08/22 キュー作成時にタグ付けするTag-on-createをサポート。AWS IAMの「aws:TagKeys」キーと「aws:RequestTag」キーが指定可能になる。
2019/08/28 AWS X-Rayを使用したキューのトラブルシューティングをサポート。
2019/11/19 AWS LambdaでAmazon SQS FIFOキューをイベントソースとしてサポートするようになる。
2019/12/11 1分間のAmazon CloudWatchメトリクスが利用可能になる。
2020/06/22 ListQueues APIとListDeadLetterSourceQueues APIでのページネーションがサポートされ、リクエストから返される結果の最大数を指定可能になる。
2020/12/17 FIFOキューのメッセージのハイスループットモードがプレビューリリースされる。
2021/05/27 FIFOキューでのハイスループットモードがGA(General Availability)になる。
2021/11/23 Amazon SQS管理の暗号化キーを使用したサーバーサイド暗号化(SSE-SQS)が利用可能になる。
2021/12/01 スタンダードキューでデッドレターキューのリドライブがサポートされる。
2022/10/04 Amazon SQS管理の暗号化キーを使用したサーバーサイド暗号化(SSE-SQS)のデフォルト有効化をサポート。
2022/11/17 属性ベースのアクセス制御(ABAC)が導入される。
2023/07/27 Amazon SQSでAWS JSONプロトコルを使ったAPIリクエストがプレビューリリースとなる。
2023/11/27 FIFOキューでデッドレターキューのリドライブがサポートされる。
2024/02/06 Amazon S3を使って最大2GBのペイロードを持つメッセージを送受信できるようになるAmazon SQS Extended Client Library for Pythonが利用可能になる。

現在のAmazon SQSの機能一覧と概要

ここからは、現在のAmazon SQSの主要な機能について詳しく解説していきます。
Amazon Simple Queue Service(Amazon SQS)は、マイクロサービス、分散システム、サーバーレスアプリケーション間でのメッセージ交換を実現するための信頼性が高くスケーラブルなフルマネージド型のメッセージキューイングサービスです。

Amazon SQSは、高い信頼性と耐久性を持つメッセージキューサービスを提供することにより、アプリケーション間での非同期処理や分散システムの効率的なメッセージ交換を可能にします。
また、自動スケーリングとデータ冗長性によってシステムの負荷変動に対応し、メッセージのロスを防ぎます。
さらに、従量課金制の料金体系はコスト効率の良いソリューションを実現し、AWS Identity and Access Management(IAM)によるアクセス管理とトランジット中および保存中のデータ暗号化によって高いセキュリティを実現します。
これらの特長に加え、他のAWSサービスとの簡単な統合が可能であり、アプリケーションの迅速な開発と柔軟な運用を行うことができます。

Amazon SQSのユースケース

Amazon SQSは多様なシナリオで活用され、システムの耐障害性と拡張性を高めるためにデザインされています。
Amazon SQSが提供するメッセージキューサービスの主なユースケースには以下のようなものが挙げられます。

  • 非同期通信
    アプリケーション間でメッセージを非同期に転送し、システムコンポーネントが独立およびスケールして処理が行えるようにします。

  • ロードレベリング
    ピークタイムの負荷や突発的なトラフィックに対応し、メッセージをキューに保持することで後続システムの過負荷を防ぐことができます。

  • 分散システムの統合
    分散アーキテクチャ内の異なるシステムコンポーネント間でメッセージを交換して連携します。

ユースケースの具体例

たとえば、以下のようなユースケースの具体例があります。

  • Eコマース注文システム
    Webアプリケーションから受け取った注文情報をSQSに送信し、注文処理サービスがキューからメッセージを取り出して順番に処理します。
    これにより、顧客が一斉に注文した場合でも、注文データが失われることなく確実に処理され、注文処理システムがダウンするリスクを最小限に抑えられます。

  • マイクロサービス間の通信
    マイクロサービスアーキテクチャを採用している際、各サービス間でのメッージのやり取りをSQSを利用して行うことができます。
    メッセージキューを使用することで、サービス間の疎結合性が保たれ、システム全体がより回復力を持って動作します。

  • ビッグデータアプリケーション
    データ集積地点からSQSを介してデータを収集し、バッチ処理やストリーム処理できるように配信することができます。
    これにより、さまざまな速度のデータ処理が可能になります。

このようにAmazon SQSは様々なユースケースで堅牢かつスケール可能なメッセージキューイングサービスを提供しており、ビジネスニーズに合わせた柔軟なアプリケーション設計を可能にします。

Amazon SQSの概念図

ここから、Amazon SQSの主な機能や特徴について説明していきますが、その前にAmazon SQSの全体像を想像しやすくするためにAmazon SQSの概念図を次に示します。

Amazon SQSの概念図
Amazon SQSの概念図

Amazon SQSでは基本的なキューを操作するアクションを提供しています。
Amazon SQSキューにメッセージを送信する役割を担うシステムをプロデューサーと呼び、Amazon SQSキューからメッセージを受信、削除する役割を担うシステムをコンシューマーと呼びます。
上記の概念図ではプロデューサーおよびコンシューマーはAWS Lambda Functionで実装されていると想定しています。

プロデューサーはSendMessageでメッセージをAmazon SQSキューに送信し、コンシューマーはAmazon SQSキューからReceiveMessageでメッセージを受信し、メッセージの処理が完了したら、DeleteMessageでメッセージを削除します。
また、概念図に記載のあるSendMessageReceiveMessageDeleteMessageといったAPIアクションの他にSendMessageBatchReceiveMessageDeleteMessageBatchといったバッチ処理のAPIアクションもあります。

Amazon SQS Standard Queuesは無制限に近いスループットでメッセージ処理ができる一方でメッセージの順序が保証されず、重複したメッセージ配信があるキューのタイプです。
一方で、Amazon SQS FIFO Queuesはスループットには上限がありますが、メッセージの順序と正確に1回のメッセージ配信を保証するキューのタイプです。
以降では、このAmazon SQS Standard QueuesとAmazon SQS FIFO Queuesについて説明します。

Amazon SQS Standard Queues(スタンダードキュー)

Amazon SQS Standard Queues(スタンダードキュー)は堅牢なマネージドメッセージキューサービスで、分散システム間でメッセージを非同期に送受信するための仕組みを提供します。
主なスタンダードキューの特徴には次のものがあります。

  • 無制限のトランザクション数
    スタンダードキューは無制限のトランザクション数をサポートしており、SendMessageReceiveMessageDeleteMessageといったAPIアクションへの呼び出し回数に上限が設けられていません。これは高い処理量やスループットが必要なアプリケーションに適しています。

  • 少なくとも1回の配信保証 ('at-least-once delivery')
    スタンダードキューはメッセージが少なくとも一度は配信されることを保証しています。しかし、スタンダードキューではメッセージが複数回配信される可能性があることに注意が必要です。

  • ベストエフォートの順序保持
    スタンダードキューでは多くの場合、メッセージは送信された順番で受信されます。しかし、スタンダードキューはメッセージの厳格な順序付けは保証しておらず、まれに順番が入れ替わることがあるため、完全な順序性が必要な場合はFIFOキューを利用することが推奨されます。

このように、スタンダードキューは耐久性と拡張性に優れたメッセージングソリューションを求めるさまざまなアプリケーションで有効に活用することができます。ただし、アプリケーションがメッセージ配信の重複や順序変動に対応可能であることが前提となります。

Amazon SQS FIFO Queues(FIFO キュー)

Amazon SQS FIFO Queues(FIFO キュー)はメッセージの厳密な順序保持と重複メッセージの排除機能を提供する特定のユースケース向けのキューサービスです。
FIFOキューは、順序保持機能によってメッセージが送信された順序通りにキューから取得されることを保証し、重複排除機能によって「正確に1回の配信」を保証します。

メッセージの厳格な順序付け(順序保持機能)

FIFOキューでは、送信されたメッセージの順番が厳密に維持されます。メッセージは先入れ先出しの原則に基づいて処理され、同じメッセージグループ内のメッセージの場合、その順序は変更されません。

正確に1回の処理(重複排除機能)

FIFOキューはスタンダードキューと異なり、重複メッセージを最小限に抑制します。FIFOキューには、デフォルトで5分間の重複排除ウィンドウが設定されており、この期間内に同一のMessage Deduplication ID(メッセージ重複排除ID)を持つメッセージが再送されても、キューには一度しか追加されません。重複排除機能に関しては以下の2つの方法があります。

  • Message Deduplication ID(メッセージ重複排除ID)の自動生成
    コンテンツベースの重複排除が有効な場合、Amazon SQSはメッセージ内容からSHA-256ハッシュを用いて一意なメッセージ重複排除IDを自動的に生成します。このIDはメッセージ本体の内容から生成され、メッセージ属性は考慮されません。

  • 明示的なMessage Deduplication ID(メッセージ重複排除ID)の指定
    開発者はメッセージ送信時に独自のメッセージ重複排除IDを指定することができます。同じ重複排除ウインドウ内で同じIDを持つメッセージが送信された場合でも、該当するメッセージはキューに一度しか追加されません。

これらの機能を活用することで、FIFOキューでの「正確に1回の処理」が実現され、メッセージの重複や失われることなく処理されることが保証されます。

スタンダードキューからFIFOキューへの移行

スタンダードキューを使用している既存のアプリケーションで、メッセージの厳密な順序性と正確に1回だけの処理機能が必要になった場合、スタンダードキューからFIFOキューへの適切な移行が必要です。この移行は、アプリケーションが要求するメッセージの順序保持と重複排除を確実に実施することを目的とする場合によく用いられます。

ただし、スタンダードキューからFIFOキューへの直接変換は不可能であり、以下のいずれかの手順によって移行します。

  • 既存のスタンダードキューを削除し、新しいFIFOキューを作成する
  • 単に新しいFIFOキューを追加し、既存のスタンダードキューはそのまま保持する

どちらの方法も、アプリケーションがFIFOキューの特性を最大限に活用し、順序性と処理の一貫性を保つための適切な設定変更を必要とします。このプロセスを通じて、アプリケーションはより高度なメッセージング要件に対応できるようになります。

スタンダードキューからFIFOキューに移行する際の移行プロセスと考慮するべき点をまとめると次のようになります。

移行プロセス
  1. キューの再作成
    スタンダードキューを直接FIFOキューに変換することはできません。新しいFIFOキューを作成するか、既存のスタンダードキューを削除後、FIFOキューとして再作成する必要があります。
  2. アプリケーションの調整
    FIFOキュー特有の機能(メッセージグループID、重複排除IDなど)を利用するために、アプリケーションコードの変更が必要です。
考慮するべき点
  • ハイスループットモードの利用
    FIFOキューのハイスループットモードを有効にすることで、メッセージ送信のスループットを最大化できます。ただし、このモードには特定の制限がありますので、使用前にAWSドキュメントで詳細を確認してください。
  • 遅延の設定
    FIFOキューでは、個別のメッセージではなく、キュー全体に対して遅延を設定することが可能です。個別メッセージの遅延設定が必要な場合は、アプリケーション側での対応が必要です。
  • メッセージグループの利用
    類似または関連するタスクをグループ化することで、メッセージの順序を保ちつつ、複数のプロセッサで並列処理を行うことができます。効果的なスケーリングのために、適切なメッセージグループIDの設計が重要です。
  • 重複排除の戦略
    重複排除IDを利用することで、同一のメッセージが重複して処理されるのを防ぎます。また、コンテンツベースの重複排除機能も有効にすることが可能です。
  • 可視性タイムアウトの管理
    メッセージの処理時間が長く、可視性タイムアウトを延長する必要がある場合、各ReceiveMessageアクションに受信リクエスト試行IDを追加して、受信試行のリトライを管理することを検討してください。

これらの変更を適切に行うことで、アプリケーションはFIFOキューの特性を最大限に活用し、より確実で効率的なメッセージ処理を実現できるようになります。

FIFOキューのハイスループット

FIFOキュー向けハイスループットは、APIごと、秒間あたりのリクエスト数を増やすサポートを提供します。
FIFOキューのハイスループットを有効にすることで、APIごとに秒間あたりのリクエスト数を増やすことができます。
FIFOキューでのリクエスト数を増やすためには、使用するメッセージグループの数を増やすことができます。

Amazon SQSはFIFOキューのデータをパーティション内に保存します。
一つのAWSリージョン内の複数のアベイラビリティーゾーンに自動的にレプリケーションされるパーティションは、キューのために割り当てられたストレージです。
ユーザーはパーティションを管理せず、Amazon SQSがパーティション管理を行います。

新しいFIFOキューや既存のFIFOキューに対してハイスループットを有効にすることができます。
FIFOキューを作成および編集する際には、以下の3つのオプションが提供されます。

  • ハイスループットFIFOを有効にする
    現在のFIFOキューのメッセージに対して、より高いスループットを利用可能にします。
  • 重複排除の範囲
    重複排除がキュー全体、またはメッセージグループ単位で行われるかを指定します。
  • FIFOスループット制限
    FIFOキュー内のメッセージに対するスループットの制限がキュー全体、またはメッセージグループ単位で設定されているかを指定します。

FIFOキューのハイスループットを有効にするには、キューの作成または編集時にハイスループットFIFOを有効にするオプションを選択します。これにより、以下の設定が自動的に行われます。

  • 重複排除の範囲がメッセージグループに設定される
  • FIFOスループット制限がメッセージグループIDごとに設定される

ハイスループットFIFOモードを有効にすると、メッセージグループごとに重複排除とFIFOキューのスループットの限界が自動で設定されます。
もし、これらの自動設定に変更が必要な場合は、キューは自動的に通常のスループットモードに戻りますが、ユーザーが指定した通りに重複排除の処理は引き続き行われます。

キューの作成または編集後は、高いトランザクション率でメッセージを送信し、受信および削除することができます。
FIFOキューのハイスループットでは、メッセージグループIDごとに1秒あたり最大3,000のメッセージを送信および受信できます。
ただし、この制限はメッセージグループIDごとに適用されるため、メッセージグループの数を増やすことで、キュー全体のスループットを向上させることができます。

Amazon SQS Standard Queues(スタンダードキュー)とAmazon SQS FIFO Queues(FIFO キュー)の違い、比較

Amazon SQS Standard Queues(スタンダードキュー)とAmazon SQS FIFO Queues(FIFO キュー)の違い、比較を表にまとめると次のようになります。

比較項目 Amazon SQS Standard Queues(スタンダードキュー) Amazon SQS FIFO Queues(FIFO キュー)
配信保証 少なくとも1回の配信。
(重複した配信の可能性もある。)
正確に1回の配信。
配信順序 ベストエフォート。
(順序が変わる可能性もある。)
メッセージブループ内でFirst-In-First-Outの順序を維持する。
スループット ほぼ無制限。 APIアクション(SendMessage、ReceiveMessage、DeleteMessage)ごとに1秒あたり最大300トランザクション。
バッチ処理ではAPIアクション(SendMessageBatch、ReceiveMessage、DeleteMessageBatch)ごとに1秒あたり最大3,000メッセージ。
ハイスループットの有効化により、さらに高いスループットを割り当てる事が可能。

Amazon SQSの主な機能

ここからは、Amazon SQSのスタンダードキューとFIFOキュー両方で利用可能である主要な機能について説明します。

Short Polling and Long Polling(ショートポーリングとロングポーリング)

Amazon SQSは、ショートポーリングとロングポーリングの2つのメッセージ受信方式を提供しています。
ショートポーリングはデフォルトの設定であり、メッセージが頻繁に到着する環境では有効ですが、ロングポーリングはメッセージ到着頻度が低い環境でコスト削減と効率化に役立ちます。

Short Polling(ショートポーリング)

ショートポーリング時は、ReceiveMessageリクエストがキューのサブセット(ランダムに選ばれたサーバー群)に対して行われ、利用可能なメッセージをすぐに返す仕組みで動作します。
メッセージが存在しない場合でも、SQSは直ちにレスポンスを返します。
このため、キュー内のメッセージ数が少なければ、連続したリクエストでメッセージを取得することがありますが、一つのリクエストでは全てのメッセージを取得しきれないこともあります。
リクエストを繰り返すことでキューからメッセージを均等に受信することができますが、メッセージがないときの繰り返しリクエストによりコストが発生し、通信量も増加するリスクがあります。

Long Polling(ロングポーリング)

ロングポーリングでは、ReceiveMessageリクエストが設定された時間(ReceiveMessageWaitTimeSeconds)まで待機し、SQSの全てのサーバーにクエリを行います。
メッセージが1つでも見つかるか、指定された待機時間が経過するまでSQSはレスポンスを保留します。
新しいメッセージが到着すれば即座にレスポンスとして返し、最大メッセージ数に達するまで他のメッセージを待ち受けます。
待機時間が終了してもメッセージが無い場合は、空のレスポンスを返します。
ロングポーリングは不必要なリクエストを減らし、偽の空レスポンス(メッセージがあるにも関わらず、レスポンスに含まれないケース)を削減し、コスト効率を改善します。
ReceiveMessageWaitTimeSecondsを0より大きい値に設定することで有効になり、最大20秒間の待機が可能です。
待機時間中に余計なトラフィックが生じないため、コストパフォーマンスが向上します。
これにより、メッセージの到着頻度が低いかアプリケーションの処理能力に余裕がある場合に、効率的なメッセージ処理を期待できます。

Dead-letter Queues(デッドレターキュー)

デッドレターキューは、処理に失敗したメッセージを隔離するために利用され、デバッグや問題解析に役立ちます。
メッセージが所定の受信試行回数(maxReceiveCount)を超えると、自動的にデッドレターキューへ移動される機能です。デッドレターキューは、問題のあるメッセージを隔離して、原因究明を容易にするために重要です。

デッドレターキューは自動的に作成されません。あらかじめキューを作成し、それをデッドレターキューとして利用する必要があります。
また、FIFOキューのデッドレターキューもFIFOキューである必要があり、同様に、スタンダードキューの場合もスタンダードキューでなければなりません。
デッドレターキューと他のキューは同じAWSアカウントおよび同じリージョン内に存在する必要があります。

maxReceiveCountは、メッセージがデッドレターキューに移動される前にソースキューからどれだけの回数受信されるかを指定します。
値が低いほど、たとえばネットワークエラーやクライアント依存エラーなど、少ない受信試行後にメッセージがデッドレターキューに移動されることになります。
ただし、システムがエラーから回復できるように、十分な再試行の機会を考慮してmaxReceiveCountの値を設定する必要があります。

メッセージの処理に失敗した原因を特定した後、またはメッセージを消費できる状態になった後は、デッドレターキューから元のソースキューへメッセージを戻すためのRedrive Policyを使用できます。
デッドレターキューからのメッセージの移動時には、APIコールの数に基づいた料金が課され、Amazon SQSの価格設定に従って請求されます。

デッドレターキューを設定するには、最初にデッドレターキューとして使用するキューを作成します。
次に、ソースキューの設定で、デッドレターキューとして使用するキューを指定し、maxReceiveCountの値を設定します。
これにより、処理に失敗したメッセージが指定したデッドレターキューに自動的に移動されるようになります。

デッドレターキューを使用すべきシナリオは、メッセージの処理に失敗した場合に、問題の原因を特定し、適切な対処を行うために必要な場合です。
例えば、外部サービスとの連携に失敗した場合や、メッセージのフォーマットが正しくない場合などが挙げられます。

デッドレターキューからメッセージを移動する方法は、Redrive Policyを使用します。
Redrive Policyは、デッドレターキューから元のソースキューにメッセージを戻すための設定です。
Redrive Policyを設定することで、デッドレターキューに溜まったメッセージを再処理することができます。

デッドレターキューのデバッグやトラブルシューティングでは、CloudWatchメトリクスを活用することができます。
デッドレターキューに関連するメトリクスを監視することで、処理に失敗したメッセージの数や、デッドレターキューに滞留しているメッセージの数などを把握できます。
これらの情報を元に、適切な対処を行うことができます。

デッドレターキューの設定や使用に関しては、実装上の注意点やベストプラクティスが多数存在するため、適切な設計と運用が求められます。
例えば、デッドレターキューのサイズを適切に設定する、デッドレターキューに滞留しているメッセージを定期的に監視する、などが挙げられます。
これらの点に留意し、慎重に設定・運用することが推奨されます。

Visibility Timeout(可視性タイムアウト)

「可視性タイムアウト」とは、メッセージの処理中に他のコンシューマー(メッセージを受信して処理するアプリケーション)がそのメッセージを受信できないようにする期間のことです。
このタイムアウト期間中、Amazon SQSが他のコンシューマーからのメッセージ受信をブロックします。
デフォルトの可視性タイムアウトは30秒ですが、0秒から12時間の間で設定可能です。

可視性タイムアウトの適切な設定は重要です。コンシューマーは、この期間内にメッセージの処理と削除を完了する必要があります。
処理が完了する前にタイムアウトが経過すると、メッセージが他のコンシューマーに再度受信される可能性があります。これにより、同じメッセージが複数回処理されるリスクを軽減できます。

ただし、スタンダードキューでは可視性タイムアウトを設定してもメッセージの重複受信を完全に防ぐことはできません(「少なくとも一度の配信」ポリシーのため)。
一方でFIFOキューではメッセージデデュープリケーションIDや受信リクエスト試行IDを使用することで、プロデューサーとコンシューマーが必要に応じて送受信を再試行できます。

インフライトメッセージ

Amazon SQSのメッセージには3つの状態があります。

  • プロデューサーからキューに送信された状態
  • コンシューマーがキューから受信した状態
  • キューから削除された状態

プロデューサーから送信されたがまだ受信されていないメッセージは「保存された状態」とみなされ、その数に上限はありません。
一方、コンシューマーが受信したが削除していないメッセージは「インフライト状態」と呼ばれ、その数には上限があります。
インフライトメッセージ数の上限はスタンダードキューでは120,000、FIFOキューでは20,000です。

可視性タイムアウトは、キューごとにデフォルト値を変更したり、メッセージ受信時に特定のタイムアウト値を指定したりできます。
12時間以上の処理時間が必要な場合は、AWS Step Functionsの使用を検討したほうが良いでしょう。

可視性タイムアウトのベストプラクティス

メッセージの処理時間が不明な場合は、コンシューマープロセスのハートビートを実装します。
例えば、初期の可視性タイムアウトを2分に設定し、コンシューマーが処理を継続する限り1分ごとに2分のタイムアウトを追加します。
処理開始後にタイムアウトが不足していることが判明した場合、ChangeMessageVisibilityアクションで新しいタイムアウト値を指定し、可視性タイムアウトを短縮または延長できます。
また、処理を行わないことを決定した場合も、ChangeMessageVisibilityアクションでタイムアウトを0に設定し、メッセージを即座に他のコンポーネントに表示して再処理できるようにすることができます。

Delay Queues(遅延キュー)

Amazon SQSの遅延キューは、メッセージをコンシューマーに配信する前に一定時間保留することができる機能です。
この機能は、例えばコンシューマーアプリケーションがメッセージの処理に追加時間を要する場合などに便利です。
遅延キューに送信されたメッセージは、指定された遅延期間が経過するまで、コンシューマーには見えない状態でキュー内に残ります。

デフォルト(最小)の遅延時間は0秒で、設定できる最大の遅延時間は以下の通りです。

  • スタンダードキューの場合、最大の遅延時間は900秒(15分)
  • FIFOキューの場合、最大の遅延時間は900秒(15分)

スタンダードキューではキューの遅延設定を変更しても、既にキューにあるメッセージの遅延には影響しません。
新しい設定は設定変更後に追加されたメッセージにのみ適用されます。
同様に、FIFOキューでも設定変更は既存のメッセージには影響せず、新しいメッセージにのみ適用されます。

遅延キューは「可視性タイムアウト」と似ていますが、両者の主な違いは以下の通りです。

  • 遅延キュー:メッセージがキューに追加された直後から隠される
  • 可視性タイムアウト:メッセージがキューから取得された後に隠される

すべてのメッセージに対して一律の遅延時間を設定する代わりに、個々のメッセージに遅延時間を指定したい場合は、後述のメッセージタイマーを使用します。
メッセージタイマーを使用すると、個々のメッセージに対して最大900秒(15分)までの独自の遅延時間を設定できます。
これは、キューレベルのDelaySeconds属性の最大値と同じです。
キューレベルのDelaySeconds属性とメッセージタイマーのDelaySeconds値の両方が設定されている場合、メッセージタイマーの値が優先されます。
つまり、メッセージタイマーが設定されている場合、キューのDelaySeconds値は無視されます。

遅延キューとメッセージタイマーを併用することで、キュー全体に対するデフォルトの遅延時間を設定しつつ、特定のメッセージに対して個別の遅延時間を指定することができます。

Message Timers(メッセージタイマー)

Amazon SQSのメッセージタイマーは、キューに追加されたメッセージごとに最初の非表示期間を指定できる機能です。
これにより、メッセージがキューに到着しても、設定した特定の時間が経過するまではコンシューマーには表示されない仕組みを持っています。
例えば、45秒のタイマーを設定したメッセージはキューに到達してから最初の45秒間はコンシューマーに見えません。

最小限(デフォルト)の遅延時間は0秒ですが、最大で15分の遅延を設定することができます。
メッセージタイマーは、AWSマネジメントコンソールやAWS SDKなどを使用してメッセージを送信する際に設定することができます。

ただし、FIFO(先入れ先出し)キューは個々のメッセージに対してこのタイマーを設定することはできません。
FIFOキューでメッセージの遅延を設定したい場合には、キュー全体に対して遅延期間を設定する遅延キュー(delay queues)を使用する必要があります。
また、個別のメッセージに設定されたメッセージタイマーはAmazon SQSの遅延キューに設定されているDelaySeconds値よりも優先されます。
つまり、遅延キューの設定よりもメッセージタイマーの設定が優先されます。

Visibility Timeout(可視性タイムアウト)、Delay Queues(遅延キュー)、Message Timers(メッセージタイマー)の違い

Visibility Timeout(可視性タイムアウト)、Delay Queues(遅延キュー)、Message Timers(メッセージタイマー)の主な違いをまとめると以下のようになります。

  • 遅延キュー
    メッセージがキューに追加された直後から隠される。
    遅延キューはキュー全体に設定されるため、キューに追加されたすべてのメッセージに遅延が適用されます。この遅延により、メッセージは消費者によって指定された時間が経過するまで取得できなくなります。
  • 可視性タイムアウト
    メッセージがキューから取得された後に隠される。
    これはメッセージが消費者によって読み取られた後、一定時間他の消費者から見えなくなるようにする設定です。これにより、メッセージの重複処理を防ぎ、消費者がメッセージの処理を完了するための時間を確保します。
  • メッセージタイマー
    個々のメッセージに対して遅延時間を設定できる。
    これにより、特定のメッセージがキューに追加されてから消費者に表示されるまでの時間を個別に制御できます。メッセージタイマーは個々のメッセージに対して異なる遅延時間を設定することができ、遅延キューと異なり、メッセージ単位でのより細かい遅延管理を可能にします。

Temporary Queues(一時キュー)

Amazon SQSの一時キュー機能はリクエスト・レスポンスパターンのようなクライアントとサーバー間でアプリケーションが一時的に使用するためのキューを提供します。
この一時キューをアプリケーションが管理下で効率的に高いスループットを実現しつつコストを抑えて動的に生成するために「Temporary Queue Client」が用意されています。

このクライアントは特定のプロセス用にオンデマンドで作成される複数の一時キューを自動的に単一のAmazon SQSキューにマッピングします。
これにより、各一時キューへのトラフィックが少ない場合でもアプリケーションはAPIコールを減らし、スループットを向上させることが可能になります。
また、一時キューが不要になると、クライアントが自動的にそれを削除します。
これは、クライアントを使用しているすべてのプロセスが正常にシャットダウンしなかったとしても行われます。

一時キューの利点は以下の通りです。

  • 特定のスレッドやプロセス専用の軽量コミュニケーションチャネルとして機能します
  • 追加コストを発生させることなく、作成および削除が可能です
  • 一時キューではない静的(通常の)Amazon SQSキューとAPI互換性があります(既存のコードでメッセージの送信と受信ができます)

例えば、サーバ側ではログインリクエストを処理するためにLoginServerクラスを作成し、クライアントからのログインリクエストをポーリングし、各メッセージに対してhandleLoginRequest()メソッドを呼び出すスレッドを起動することができます。
handleLoginRequest()メソッド内では、doLogin()メソッドを呼び出してログイン処理を行います。

また、キューのクリーンアップを確実に行うために、アプリケーションが一時キュークライアントを使用しなくなったときは、shutdown()メソッドを呼び出す必要があります。
同様に、AmazonSQSRequesterインターフェースのshutdown()メソッドを使用することもできます。これにより、一時キューが適切に削除され、リソースの無駄を防ぐことができます。

Amazon SQSの一時キューの特徴が活かせるリクエスト・レスポンスパターンのような一時的なメッセージ交換を必要とするアプリケーションの具体的な例としては、以下のようなものが挙げられます。

  • ウェブアプリケーションのログイン処理
    ユーザーがログインフォームに入力した情報を、ウェブサーバーからバックエンドのサーバーに送信し、認証結果を受け取る処理。この場合、各ログインリクエストに対して一時キューを作成し、バックエンドサーバーとの通信に使用することで、効率的かつ独立したメッセージ交換が可能になります。
  • 外部APIとの連携
    アプリケーションが外部のAPIサービスにリクエストを送信し、その応答を受け取る処理。例えば、決済サービスやソーシャルメディアのAPIなどと連携する場合、一時キューを使用してリクエストと応答のメッセージ交換を管理することで、安定性と拡張性を向上させることができます。
  • ファイル処理の非同期化
    ユーザーがアップロードしたファイルを、バックグラウンドで非同期的に処理するアプリケーション。この場合、一時キューを使用してファイル処理のリクエストを管理することで、ユーザーインターフェースのレスポンス性を維持しつつ、バックグラウンド処理を効率的に実行できます。
  • チャットアプリケーション
    ユーザー間のメッセージ交換を行うチャットアプリケーション。各ユーザーのメッセージ送信リクエストに対して一時キューを作成し、メッセージの配信と受信の管理に使用することで、スケーラブルかつリアルタイムなメッセージ交換を実現できます。
  • 分散処理システム
    大規模なデータ処理を複数のワーカーノードで分散して実行するシステム。一時キューを使用して、ジョブの割り当てとワーカーノード間の中間結果の受け渡しを管理することで、効率的かつ耐障害性の高い分散処理を実現できます。

これらの例では、一時キューのもつ動的な作成と削除、高いスループットとコスト効率、独立した通信チャネルといった利点を活かすことで、アプリケーションのパフォーマンスと拡張性を向上させることができます。

Attribute-Based Access Control(ABAC) (属性ベースのアクセス制御)

Amazon SQSではAttribute-Based Access Control(ABAC)により、IAMポリシーを用いて、タグを付与したユーザーやAWSリソースに基づいて細かくアクセス権限を管理することができます。
これによって、SQSキューに関連付けられたタグやエイリアスに基づいて、認証されたIAMプリンシパルがポリシーを編集したり、権限付与を管理することなくAmazon SQSキューへのアクセスを許可することが可能になります。

ABACを使用すると、ビジネスロールごとに追加されたタグを利用してIAMアクセス権限を設定することにより、パーミッション管理をスケールすることができます。
また、新しいリソースを追加する際に毎回ポリシーを更新する手間を省くことができます。
さらに、IAMプリンシパルにタグを付与してABACポリシーを作成し、IAMユーザーロールに付いたタグがAmazon SQSキューのタグと一致する時に、Amazon SQS操作を許可するポリシーを設計することもできます。

ABACの利用による利点としては、異なる役割のために異なるポリシーを作成する必要が減少し、運用上の負担が軽減されることが挙げられます。
加えて、メンバーの迅速なスケールアップが実現可能であり、新しいリソースに対する権限が適切にタグ付けされた場合に自動的に付与されます。
さらに、リソースアクセスを制限するためにIAMプリンシパルの権限を使用し、AWS CloudTrailを通じてどのユーザーがリソースにアクセスしているかを追跡することができます。

ABACによる具体的な制御としては、リソースタグやリクエストタグが特定のキーと値に合致する条件下でのみ、Amazon SQSキューに対する操作を許可するIAMポリシーを作成することが挙げられます。
AWS管理コンソールやAWS CloudFormationを使用して、ABACポリシーを持つIAMユーザーやAmazon SQSキューを作成することも可能です。

ABACを適切に活用することで、Amazon SQSをより安全で柔軟な運用が可能となり、特に大規模な環境で組織のセキュリティ要件を満たしつつ、効率的なリソース管理が可能となります。

Amazon SQSのベストプラクティス

Standard QueuesとFIFO Queuesで共通するベストプラクティス

Amazon SQSを効率的かつコスト削減しながら使用するために、以下のベストプラクティスが推奨されます。これらのことはStandard QueuesとFIFO Queuesの両方に適用可能なものです。

  • メッセージの効率的な処理
    メッセージを受信してから処理し削除するまでの時間に基づいて、Visibility Timeout(可視性タイムアウト)を適切に設定します。Visibility Timeoutの最大値は12時間ですが、各メッセージに対してそれをフルに設定することはできない場合もあるため注意が必要です。また、メッセージの処理時間が未知数の場合は、初期Visibility Timeoutを設定した後、作業中に定期的に延長することを検討する必要があります。

  • リクエストエラーの取り扱い
    AWS SDKを使用していれば自動再試行とバックオフロジックが利用可能です。SDKを使用していない場合は、ReceiveMessageアクションのリトライ前に一定時間待機するようにしてください。待機時間は指数関数的にバックオフすることが望ましいです。例えば、最初のリトライ前に1秒待機し、2回目は2秒、3回目は4秒のように待機時間を増やしていきます。

  • ロングポーリングの設定
    ロングポーリングを利用することで無駄なポーリングを回避し、コストを削減できます。WaitTimeSecondsパラメーターは最大20秒まで設定可能です。なお、HTTPレスポンスのタイムアウトは、このパラメーターよりも長く設定する必要があります。例えば、WaitTimeSecondsを20秒に設定する場合、HTTPレスポンスのタイムアウトは30秒以上に設定します。

  • 問題のあるメッセージのキャプチャ
    処理することが難しいメッセージをDead-letter Queueへ移動させる設定を行い、正確なCloudWatchメトリクスを取得することが重要です。Dead-letter Queueへ処理に失敗したメッセージを移動することで、問題のあるメッセージを分離し、メインのキューの処理を滞らせることなく、エラーの原因を調査することができます。

  • Dead-letter Queueの保持期間設定 Dead-letter Queue(DLQ)では正常に処理できなかったメッセージを一時的に保管し、問題解決や分析のために後から確認することができます。そのため、DLQのメッセージ保持期間は、通常のキューのそれよりも長く設定するのが一般的です。これにより、問題のあるメッセージを十分な時間をかけて調査し、対処することが可能となります。スタンダードキューとFIFOキューでの扱いは以下のように異なります。
    スタンダードキュー:メッセージがDead-letter Queueに移動されると、エンキューされた時点のタイムスタンプが保持され、その時点からの保持期間が継続します。
    FIFOキュー:メッセージがDead-letter Queueに移動された時点でタイムスタンプがリセットされ、新たな保持期間が開始されます。
    このように、キューのタイプに応じてDLQの保持期間の管理が異なります。この違いを理解することが、効果的なメッセージ処理システムの設計と管理には重要です。

  • 一貫性のないメッセージ処理の回避
    分散システム特有の問題として、メッセージが配信済みとマークされているにも関わらず、コンシューマーが受け取っていない場合があります。そのため、Dead-letter Queueへの最大受信回数を1に設定することは推奨されません。最大受信回数を2以上に設定することで、一時的なエラーによってメッセージが失われるリスクを軽減できます。

  • リクエスト-レスポンスシステムの実装
    リクエスト-レスポンスパターンやRPC(リモートプロシージャコール)システムを実装する際、返信キュー(クライアントがサーバーからの応答を受け取るために用いるメッセージキュー)を効率的に使用することが重要です。特定のメッージごとに返信キューを新たに作成するのではなく、システム起動時に各プロデューサー(リクエストを送信する側)ごとに一つの返信キューを設定します。また、リクエストと応答を一致させるために相関IDを使用することで、返信キューの管理を簡素化し、システムの全体的なパフォーマンスを向上させることができます。これにより、複数のリクエストや応答を効率的に処理し、システムのレスポンス時間の短縮とリソースの最適化が期待できます。

  • コスト削減 メッセージアクションのバッチ処理を行い、Java用AWS SDKに含まれるBuffered Asynchronous Clientを活用することで、クライアント側のバッファリングとリクエストバッチングを組み合わせることができます。これにより、APIリクエストの回数を減らし、コストを削減できます。

  • 適切なポーリングモードの使用
    ロングポーリングは、キューが空の場合でも不要なReceiveMessage呼び出しを避けるために推奨されます。この方法ではサーバーがメッセージを受け取るか、設定した待機時間が終了するまで応答を保留することで、API呼び出しの回数を減らし、コストを節約します。一方で、ショートポーリングはキューにメッセージがあるかどうかにかかわらず、すぐにレスポンスを返すため、即時性が求められるアプリケーションに適していますが、空のレスポンスにも料金が発生するためコストが増加する可能性があります。そのため、アプリケーションの要件に応じて、コストとレスポンスの速さを考慮して最適なポーリングモードを選択することが重要です。

FIFO Queuesのベストプラクティス

Amazon Simple Queue Service(SQS)のFIFOキューを最も効率的に活用するためには、いくつかのベストプラクティスを理解し、適切に適用することが重要です。以下では、メッセージ重複排除IDおよびメッセージグループIDの最適な利用方法について説明します。

メッセージ重複排除IDの使用
  • メッセージの一意性の確保
    メッセージ重複排除IDは、送信されたメッセージが重複していないことを保証するためのトークンです。特定のメッセージ重複排除IDで正常に送信されたメッセージは、同じIDで送信される他のメッセージと間違って配信されないように、5分間の重複排除インターバル内で受け入れられますが配信されません。これにより、メッセージの重複を防ぎ、一意性を確保できます。

  • メッセージ重複排除IDの提供
    プロデューサーは、全く同じメッセージ本文を持つメッセージや、同じ内容だが異なる属性を持つメッセージ、または異なる内容でもSQSが重複とみなすべきメッセージ(リトライカウント含む)に対して、それぞれメッセージ重複排除IDを指定する必要があります。これにより、SQSは重複メッセージを適切に処理できます。

シングルプロデューサー/シングルコンシューマーシステムにおける重複排除

単一のプロデューサーと単一のコンシューマーを持つシステムでは、一意な本文を持つメッセージには、コンテンツベースの重複排除を有効にします。この場合、プロデューサーはメッセージ重複排除IDを省略することができます。また、コンシューマーは受信リクエスト試行IDを提供する必要はありませんが、提供することがベストプラクティスとされています。これにより、シンプルなシステム設計が可能になります。

アウトエージ回復のための設計

FIFOキューの重複排除プロセスは時間に敏感です。アプリケーションを設計する際には、プロデューサーとコンシューマーが、クライアントやネットワークのアウトエージから回復できるようにしなければなりません。特に、SQSの重複排除間隔が5分であることをプロデューサーが認識する必要があります。アウトエージが5分以上続く場合、プロデューサーは新しいメッセージ重複排除IDを使用してメッセージを再送信する必要があります。

メッセージグループIDの使用
  • メッセージグルーピングの実施
    同じメッセージグループIDを持つメッセージは、そのメッセージグループに関して厳密な順序で逐次処理されます(異なるメッセージグループ間では順序が保証されません)。複数のオーダー済みメッセージグループをキュー内で交互に処理することで、複数のコンシューマーが処理を行うことができますが、各ユーザーのセッションデータはFIFO方式で処理されます。これにより、グループ内のメッセージ順序を保証しつつ、並列処理を実現できます。
複数のプロデューサー/複数のコンシューマーシステムにおける重複排除

スループットと待ち時間を優先する複数のプロデューサーと複数のコンシューマーを持つシステムでは、メッセージごとにユニークなメッセージグループIDを生成することが推奨されます。これにより、順序は保証されないものの、重複が排除されます。システムのスケーラビリティを確保しつつ、メッセージの重複を防ぐことができます。

受信リクエスト試行IDの使用
  • リクエストの重複排除
    長期にわたるネットワークアウトエージ中にSDKとAmazon SQS間の接続問題を経験した場合、受信リクエスト試行IDを提供し、SDK操作が失敗した時は同じIDを使ってリトライすることがベストプラクティスです。これにより、ネットワークの問題によって同じメッセージが複数回受信されるのを防ぐことができます。

上記のベストプラクティスを適切に適用することで、Amazon SQS FIFOキューを使ったアプリケーションのパフォーマンスと信頼性を最大化できます。システムの要件に応じて、適切なベストプラクティスを選択し、実装することが重要です。

<参考資料>
AWS Documentation(Amazon Simple Queue Service)
Tech Blog with related articles referenced

まとめ

今回はAmazon SQSの歴史年表を作成して、Amazon SQSの機能一覧と概要を見てきました。

分散コンピューティング環境におけるメッセージキューイングサービスであるAmazon Simple Queue Service(Amazon SQS)は、最初のAWSインフラストラクチャのサービスとして2004年にアナウンス、2006年にGAとなりました。
2004年11月に発表された当時の反応は"Huh? Why would Amazon do that?"だったそうです(参考:The AWS Blog: The First Five Years)。
Amazon SQSはそれから20年近く経過した現在でも、マイクロサービスアーキテクチャ、分散システム、サーバーレスコンピューティングなどの現代的なコンピューティングにおいて重要なメッセージングとキューイングという非常に重要なコンポーネントをアップデートをしながら提供し続けています。
このような現在の状況からわかるように、当時は理解されにくかったAmazon SQS発表当時のビジョンや設計思想は将来のニーズやシステムアーキテクチャの進展を的確に捉えていたことがわかります。

Amazon SQSは当初からGUIではなくAPI経由での利用を最優先にしていたことで、独立した機能として他のシステムと疎結合な連携が柔軟にでき、利用目的の変化にも対応しやすいIaaSとして、その当時すでにサーバーレス、マイクロサービス、フルマネージドサービスという概念を実現していたことが伺えます。

今後も継続的にAmazon SQSがどのような機能を提供していくのかその動向をウォッチしていきたいと思います。

なお、今回の記事の英語版やAmazon SQS以外のサービスも含めたAWSサービス全体の歴史年表もありますので、興味がありましたら御覧ください。

Written by Hidekazu Konishi
Hidekazu Konishi (小西秀和), a Japan AWS Top Engineer and a Japan AWS All Certifications Engineer

執筆者小西秀和

Japan AWS All Certifications Engineer(AWS認定全冠)の知識をベースにAWSクラウドの活用に取り組んでいます。
Amazon.co.jp: 小西 秀和: books, biography, latest update
NRIネットコムBlog: 小西 秀和: 記事一覧