"SNS→Lambda" v.s. "SNS→SQS→Lambda"
SQSを挟むと、Lambdaの実行中に失敗したときに指定回数だけリトライして、その後、そのキューに DLQ が設定してあればそこにメッセージが送られる。DLQとしてはSQSキューのみを指定できる。 SQSを挟まないと、Lambdaの実行中に失敗したときに3回まではリトライされ、その後、そのLambdaに DLQ が設定してあればそこにイベントが送られる。DLQとしてはSNS TopicまたはSQSキューが指定できる。 SNSからLambdaを呼ぶとイベント内に何個のメッセージが入っているかは不定1個のメッセージが入っている
SQSからLambdaを呼ぶとイベント内に何個のメッセージが入っているかは不定(最大10?)
多少とりこぼしても良いから「手軽に作りたい」「早くメッセージを伝えたい」という場合はSQSを経由させない
「確実に全部のメッセージを送りたい」「万が一とりこぼした場合はその情報を残しておいて、再度送れるようにしたい」という場合はSQSを経由させる
というのが良さそう。
発行されるメッセージすべてが正常に処理されることが必要不可欠である場合は、通知が SQS キューにも (他のトランスポート経由の通知に加えて) 配信されるように設計してください。
ポリシーはエンドポイントによって、以下のように異なります。
SQS: SQS キューが利用できない場合、SNS は直ちに 10 回、続いて 20 秒間隔で 100,000 回の再試行を行います。つまり 23 日あまりで合計 100,010 回の再試行が行われます。この再試行後に配信されないメッセージは SNS から破棄されます。
Lambda: Lambda が利用できない場合、SNS では 1 秒間隔で 2 回、続いて 1 秒から 20 分までの指数的バックオフで 10 回、最後に 20 分間隔で 38 回の再試行が行われます。つまり、13 時間あまりで合計 50 回の再試行が行われます。この再試行後に配信されないメッセージは SNS から破棄されます。
↑これを見ると直接Lambdaに繋いでおいてもInvokeされないということはほとんどなさそう。とりこぼしてもマニュアルでのオペレーションが発生しないようなケースならSQSを省略しちゃってよさそう。
ポーリングベースの AWS サービス (Amazon Kinesis、Amazon DynamoDB、Amazon Simple Queue Service) の場合、AWS Lambda はストリームまたはメッセージキューをポーリングし、Lambda 関数を同期的に呼び出します。
#Lambdaの多重起動 に書いてあるように同期か非同期かで呼び出し回数が変わるのも割と大きい違い?でも前段にSNSがいるとそこで1回以上の配信になってしまうのであんまり意味ない?いや、SQSでFIFOキューを設定して重複排除の設定すれば確実に1回にすることができる。 ↓ちょっと前提が違うけど参考になるもの(このページはSNS前提でSQSを使うかどうかを調べたことを書いているけど、↓はSQSを使う前提でSNSを使うかという話)
SNSトピックを挟むデメリット
SNS topicの構築(SQSとの連携設定等)の手間が増える
コンポーネントが増え、複雑性が増すため、トラブルの原因が増える
SNSの課金が余計に掛かる
SNSトピックを挟むメリット
より抽象的
ドレーニングポイント
拡張ポイント
このページのタイトルとは直接は関係しないけど他にもKinesisDataStreamを使うという選択もある