Amazon SNS で構築する Pub/Sub メッセージング - ファンアウトパターンとフィルタリング

SNS によるトピックベースのメッセージング、サブスクリプションフィルター、SQS ファンアウトパターンを解説します。

SNS の概要

SNS は Pub/Sub メッセージングサービスで、1 トピックあたり最大 1,250 万サブスクリプションをサポートし、メッセージサイズは最大 256 KB です。パブリッシャーがトピックにメッセージを送信し、トピックをサブスクライブしている全サブスクライバーにメッセージが配信されます。SQS がポイントツーポイントのキューイングであるのに対し、SNS は 1 対多のファンアウトを実現します。Standard トピックはベストエフォートの順序で配信し、FIFO トピックは厳密な順序保証と重複排除を提供します (FIFO の上限はメッセージグループあたり毎秒 300 メッセージ)。サブスクリプションプロトコルとして SQS、Lambda、HTTP/S、Email、SMS、Amazon Data Firehose (旧 Kinesis Data Firehose) に対応し、1 つのトピックから異なるプロトコルの複数サブスクライバーに同時配信できます。

ファンアウトとフィルタリング

SNS + SQS ファンアウトパターンでは、SNS トピックに複数の SQS キューをサブスクライブし、1 つのメッセージを複数のコンシューマーに並行配信します。注文イベントを在庫管理キュー、配送キュー、通知キューに同時配信するパターンが典型的です。サブスクリプションフィルターポリシーはメッセージ属性に基づくフィルタリングで、サブスクライバーが必要なメッセージのみを受信します。フィルターポリシーは MessageAttributes (デフォルト) または MessageBody をスコープとして設定でき、文字列の完全一致、プレフィックス一致、数値範囲、exists 演算子を組み合わせた複合条件を定義できます。FIFO トピックはメッセージグループ ID で順序を制御し、同一グループ内のメッセージは厳密に FIFO で配信されます。異なるグループ間は独立して並行配信されるため、スループットを確保しながら必要な部分のみ順序を保証する設計が可能です。

デッドレターキューとリトライ

SNS のサブスクリプションにデッドレターキュー (DLQ) を設定すると、配信に失敗したメッセージが SQS キューに退避されます。 HTTP/S エンドポイントへの配信はリトライポリシー (即時リトライ、バックオフリトライ) で再試行回数と間隔を制御します。HTTP/S 配信のリトライの既定のポリシーは 4 つの段階で構成され、独自のポリシーを設定できるプロトコルは HTTP/S です。 Lambda サブスクリプションは Lambda の非同期呼び出しのリトライポリシーに従います。配信ステータスログを CloudWatch Logs に出力し、配信の成功率とエラー原因を分析できます。配信ステータスログには成功と失敗のサンプリング率を個別に設定でき、成功ログのサンプリング率を低くするとコストを抑えられます。クロスアカウントのトピックアクセスはリソースベースポリシーで制御します。

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

メッセージ属性の設計はフィルタリング効率に直結します。フィルタリングに使う属性は MessageAttributes に含め、ペイロード本体のパースをサブスクライバー側で不要にする設計を推奨します。Standard トピックではメッセージの重複配信 (at-least-once) が発生するため、コンシューマーは冪等性を確保する必要があります。Large message payload (256 KB 超) を扱う場合は、S3 にペイロードを格納し SNS メッセージには S3 参照のみを含める Extended Client Library パターンを採用します。FIFO トピックでは MessageDeduplicationId の設計が重要で、コンテンツベース重複排除を有効にすると本文ハッシュで自動判定しますが、意図しない重複排除に注意が必要です。暗号化には SSE-SNS (AWS 管理キー) と SSE-KMS (CMK) の 2 方式があり、クロスアカウントの場合は CMK のキーポリシーで配信先アカウントに復号権限を付与する設計が必要です。

EventBridge との使い分け

SNS と EventBridge はどちらもイベント駆動アーキテクチャの基盤ですが、適用領域が異なります。SNS はシンプルな属性フィルタリングで足りるファンアウトに向いています。EventBridge はイベントの構造 (JSON ボディの任意のフィールド) に対する高度なパターンマッチ、スケジュールトリガー、SaaS 統合 (Shopify、Zendesk など) が必要なケースに適しています。料金の面では、SNS は SQS への配信に料金がかからず (SQS の料金は別)、EventBridge はイベントごとに課金されます。一方、少数のルールで複雑なルーティングを行うケースでは EventBridge のルールベースの設計は保守しやすくなります。両者を組み合わせ、EventBridge でルーティング後に SNS でファンアウトする構成も有効です。

SNS のコスト管理

SNS のコストはパブリッシュ数と配信先のプロトコルで決まります。SQS への配信は無料のため、SNS → SQS → Lambda のパターンは SNS → Lambda の直接配信と比較してコスト面で有利な場合があります。HTTP/S 配信は通知の数で課金され、SMS の料金は送信先の国で異なります。メッセージフィルタリングで不要な配信を削減し、Lambda の実行回数を減らせます。大量のメッセージを処理する場合、メッセージのバッチ化 (1 メッセージに複数イベントを含める) でパブリッシュ数を削減できます。FIFO トピックは Standard と別の料金 (メッセージの数とペイロードのデータ量) で、順序保証の要否に応じて Standard と使い分けます。

まとめ

SNS は Pub/Sub メッセージングでファンアウトパターンを実現するサービスです。サブスクリプションフィルターで属性に基づく効率的なメッセージルーティングを行い、DLQ で配信に失敗したメッセージを捕捉します。SQS への配信は無料のため、SNS → SQS → Lambda のパターンでコスト効率の高い非同期処理を構築し、FIFO トピックで必要箇所のみ順序保証を適用します。EventBridge との使い分けにより、スループット要件とルーティング複雑度に応じたイベント駆動アーキテクチャを設計できます。

参考資料 (AWS 公式)

本ページの一次情報は AWS 公式サイトと公式ドキュメントです。最新の仕様と料金は次の公式ページで確認できます。

本ページと公式ドキュメントの記述が食い違う場合は、公式ドキュメントを正としてください。

共有する