← AWSサービスの内部原理 コース
49. SNSはpub/subの配達員 — トピックが1通をN通に複製する
SNSのトピックに1通を発行すると、それがサブスクリプションの数だけ複製されて別々のエンドポイントへ配られる——その「1通→N通」の流れと、なぜSNS+SQSという定番構成が生まれるのかを、注文処理の例で図に追っていきます。
① 発行者と購読者を切り離す論理チャネル
Publisher注文サービス
購読者が誰か・何人いるかを知らない購読者リストを保持
SNS Topicorder-events
論理アクセスポイント / 通信チャネルSubscriber購読を登録
発行者が誰かを知らない- 公式定義(welcome.html): トピックは "a logical access point and communication channel"。SNSは "message delivery from publishers (producers) to subscribers (consumers)" を担う。
- 発行者と購読者はトピックというアドレスだけを共有し、互いを直接知らない——pub/subパターンの核心。
トピックは発行者と購読者の間に立つ論理チャネル。両者は互いを知らずトピックだけを共有するので、購読者を足しても引いても発行側のコードは一切変わらない。これが疎結合の実体。
② 1通がサブスクリプション数だけ複製される
SNS Topicorder-events
1通 publishSQS Queue注文処理
Lambda在庫更新
HTTP(S)外部Webhook
- 購読可能なエンドポイント種別(welcome.html): Amazon SQS / Lambda / HTTP(S) / Email / Mobile push / SMS / Amazon Data Firehose / サービスプロバイダ(Datadog, MongoDB, Splunk 等)。種類の違うエンドポイントが同じトピックに混在できる。
- ファンアウト定義: "a message published to an SNS topic is replicated and pushed to multiple endpoints ... This allows for parallel asynchronous processing"。
- A2A/A2P両対応: "SNS supports both Application-to-Application (A2A) and Application-to-Person (A2P) messaging"——アプリ間と対人の両方を1つのトピックから同報できる。
- 1つの入力が複数の枝に分かれて複製されていく——DynamoDB編・Lambda編で触れた「木構造の複製」と同じ形で、根が1、葉がNになる。
発行は1回、配達はN回。SNSは1通を購読数だけ複製し、種類の違うエンドポイントへ並列にプッシュする。だから「注文が入った」を1回発行するだけで、処理・在庫・通知が同時に走り出す。
③ push(SNS)とpull(SQS)——配り方が正反対
SNS = push来た瞬間 届けに行く
貯めておく場所ではないSQS = pullキューに永続化して貯める
再試行→破棄配信ポリシーで再試行、使い切ると破棄
DLQ設定時を除く消費者がpull自分のペースで取りに来る
保持期間内は取りに来るまで待つ- Lambda編の伏線回収: 「SNSは非同期呼び出し=push、SQSはポーラー=pull」の裏側は、メッセージの配り方の向きの違い。
- 根拠(sns-message-delivery-retries.html): "When the delivery policy is exhausted, Amazon SNS stops retrying the delivery and discards the message—unless a dead-letter queue is attached to the subscription."
- SNSの受け手は受け取れる状態でいることが前提。届かなければ再試行するが、届けきれなければ最終的に破棄される。
SNSは「配達員」——来た瞬間に届けに走り、留守なら再訪するが、いつまでも荷物を預かってはくれない。SQSは「私書箱」——貯めておいて相手が取りに来る。即時性と「取りに来るまで保管」は、この時点ではトレードオフになっている。
④ 定番のSNS+SQS——即時性と永続性を合成
注文サービス
複製して各キューへ即 push(即時性)
SNS Topic
消費側が自分のペースで pull(ペース制御)
SQS(A)注文処理用
キューが永続化(取りこぼさない)SQS(B)分析用
EC2: 注文処理フルフィルメント
EC2: 分析データウェアハウスへ
- welcome.html の Fanout 例: 注文発行→"SQS queues that are subscribed to the SNS topic receive identical notifications for the new order"→EC2が注文処理/フルフィルメント、別EC2がデータウェアハウスで分析。
- テスト環境へ本番データを複製する用途にも同じ形が使える(ただしデータプライバシー/セキュリティに注意、と公式が明記)。
SNS単独のpushは速いが貯められない。SQS単独では1通のメッセージは1つの消費者にしか渡らず、同報ができない。両者を直列に挟むと「1発行で全キューに即時配布」しつつ各消費者が「自分のペースで確実に処理」できる。SNS+SQSが定番なのは、この2つの弱点を互いに埋め合わせる合成だから。
⑤ フィルタポリシー——同報からルーティングへ
publish属性 event=order.created
type=digital購読ごとに判定
SNS Topic全条件を満たせば配達、1つでも外れれば非配達
決済キューpolicy: event=order.created
一致 → 配達配送キューpolicy: type=physical
不一致 → 非配達監査ログpolicy なし
全メッセージ受信- 既定挙動(sns-message-filtering.html): "By default, an Amazon SNS topic subscriber receives every message that's published to the topic. To receive only a subset of the messages, a subscriber must assign a filter policy to the topic subscription."
- 照合ルール: "If all of the message attributes or message body properties satisfy the conditions ... Amazon SNS sends the message to the subscriber. Otherwise, Amazon SNS doesn't send the message to that subscriber."
- 照合対象はサブスクリプションの FilterPolicyScope で選ぶ: MessageAttributes(既定)/ MessageBody(本文が整形されたJSONである前提)。"If no filter policy scope is defined for an existing filter policy, the scope defaults to MessageAttributes."
- 発行側は相変わらず1通投げるだけ。振り分けの知識は購読の集合に宿る。
フィルタポリシーは「購読側が受け取りたい部分集合を宣言する」仕組み。これにより1つのトピックが、宛先ごとに中身を振り分けるルーティング装置になる。発行側は何も変えず、購読を足すだけで新しい経路が生える——②の疎結合がそのまま活きている。