📖

SQSのLambdaトリガーの仕組みとスロットリングエラー

2022/03/13に公開

概要

業務でSQSのLambdaトリガーを使用しました。
スロットリングエラー発生時の仕様が分かりづらく、理解に時間がかかったので整理します

Lambdaトリガーの裏側の仕組み

SQSのEvent Source Mappingという機能のLambdaトリガーという位置づけになります。

イベントという言葉からPush型の仕組みをイメージしますが、実際には裏側で5個のLambdaが20sのロングポーリングをし続ける仕組みになっています。

そしてSQSのなかにメッセージがあれば、トリガーとしてマッピングされているLambda関数にメッセージを渡してくれます。

  1. 5個のLambdaがSQSをロングポーリング
  2. メッセージがあるとLambdaを実行

Lambda サービスは 5 つのパラレルロングポーリング接続を使用して SQS キューのポーリングを開始します。

https://aws.amazon.com/jp/blogs/news/aws-lambda-adds-amazon-simple-queue-service-to-supported-event-sources/

料金

ロングポーリング用のLamabdaに関しては料金はかかりませんが、SQSへのリクエストは課金対象です。(めちゃくちゃ安いので気にしなくて良いレベルですが)

スロットリングエラー

SQSのEvent source mappingを使う場合、Dead Letter Queueも併用するケースがほとんどだと思います。

しかし大量のメッセージが短時間にSQSにキューイングされた時に、Lambdaの同時実行数の制限に引っかかり、メッセージが処理できないことが想定されます。

この時にvisibility timeoutとreceive countがどのように扱われるのか最初わかりませんでした。

結論としては、スロットリングエラーが起こった場合、visibility timeoutぶんの時間が経過するまではLambdaのリトライが行われるようです。
そのため

  1. スロットリングエラー発生
  2. 該当のメッセージはvisibility timeoutが経過するまで2回目の処理が行われない

のではなく

  1. スロットリングエラー発生
  2. visibility timeoutが経過するまでは複数回リトライされる(おそらくロングポーリング用のLambdaがメッセージを保持しているのでreceive countは+1だけされ+nされない)

という動きになります

To allow your function time to process each batch of records, set the source queue's visibility timeout to at least six times the timeout that you configure on your function. The extra time allows for Lambda to retry if your function is throttled while processing a previous batch.

https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html

SQS visibility timeout >= 6 * lambda timeout

公式ドキュメントでこのような設定値を推奨しているのは、上記のような仕組みが背景にある殻のようです。

Discussion