サーバーレスのイベント駆動はSNS-Lambdaで十分ではないかと思う話
以前「SNS-Lambdaの構成にするなら間にSQSを入れないとダメだ!」という意見の方とお話をする機会があり、
それって本当かなあ、と腑に落ちなかったので考えてみました。
SQS-Lambdaの前にはSNSを入れたほうがいい
SQSの前にはSNSを入れたほうがいい…は以前から言われている話です。
この理由は分かりやすく、送信側を抽象化出来るからです。
送信側が直接SQSに送っている場合、送り先を増やしたり変更したりする度に、送信側を修正しなければなりません。
しかしSNSを挟むことで、送信側を弄らず、SNSからのsubscriptionを変更するだけで上記のような変更に対応できます。
SNS-Lambdaの間にはSQSを入れたほうがいいのか
SNS-Lambdaの危険な点
以前お話した方がSNS-Lambdaの間にSQSが必須と考える理由は「誤って大量のイベントが流れた際、アカウントのLambdaの同時実行数を食い潰して他のLambdaが実行できなくなるから」でした。
ただ、これはLambda関数ごとに最大同時実行数を指定しておけば済む話のような気もします。
最大同時実行数を設定することでスロットリングが生じやすくなりますが、最大6時間はエクスポネンシャルにリトライしてくれる模様。
SQSを挟むメリット
必須でないと思う一方、SQSを挟むことによるメリットも散見されました。
リトライ
一番大きいのがこれだと思います。
関数が実行された上でエラーになった場合、2回リトライした上で失敗したらイベントは破棄されます。この際、デッドレターキューが設定されていればそちらに送られます。要するに、失敗したら割と簡単に捨てられます。
SQSを挟むことで最大14日間キューに保持し、しつこくリトライを行うことができます。
送信側、受信側の分離
SNSを送信側に、SQSを受信側に置くことで、アカウントやマイクロサービスをまたいでのイベント送受信で責務を明確に分離できます。
送信側は自身で管理するSNSにイベントを送信すればよく、受信側は自身で管理するSQSで必要なものをsubscriptionすれば済みます。
結論
SQSを挟むメリットはあるものの、必須というほどではないと思います。
SNS-Lambdaだと関数エラーで3回しかリトライしてくれないので、AWS不具合が起きた場合なんかにデッドレターキューに行ったイベントにいちいち対処するのは面倒です。
その点SQSを挟めば復旧後のリトライで通る可能性が高いので、何かする必要は無さそうです。