SQS標準キューとLambdaで発生するスロットリングエラーの原因と回避方法

はじめに
こんにちは
株式会社BTMでエンジニアをしている島谷です。
AWSのSQS(Simple Queue Service)標準キューは、メッセージの順序保証は不要だが高いスループットが求められる場合に非常に便利です。しかし、以下のように、AWS LambdaのイベントソースにSQSを使い大量のメッセージを処理する際にスロットリングエラーが発生することがあります。
スロットリングエラーとは?
スロットリングエラーとは、AWS Lambdaが設定された同時実行数の上限に達した場合や、Lambdaが受け取るリクエスト量が過剰な場合に新しいリクエストを処理できずに発生するエラーです。
標準キューにおける原因
1. Lambdaの同時実行数制限
Lambdaには同時実行数の上限があり、例えば5に設定すると一度に5インスタンスしか動きません。標準キューは順序保証せず同時に複数配信するため、制限超過でメッセージが残りスロットリングが発生します。
以下の条件で試行し、14件のスロットリングエラーが発生しました:送信11件・同時実行1・バッチ1・処理時間1秒・可視性タイムアウト30秒・受信待機10秒・DLQなし。
リトライはバックオフ戦略で行われます(公式ドキュメント)。
2. バッチサイズと処理時間の不一致
バッチサイズは一度に受け取る最大レコード数です。サイズ大で処理が長いと次の受信前に同時実行が満杯になりスロットリングが起こります。
回避方法
1. 同時実行数の増加
同時実行数を増やせば並列処理数が増え、スロットリングを防げます。ただし課金も増えるため、最小限に調整します。
2. バッチサイズの調整
バッチサイズを小さくすると1実行あたりの負荷が軽減し、処理スループットが改善します。例:10→5
resource "aws_lambda_event_source_mapping" "sqs_trigger" {
event_source_arn = aws_sqs_queue.standard_queue.arn
function_name = aws_lambda_function.standard_lambda.arn
batch_size = 5 # 負荷を軽減
enabled = true
}
モニタリング→調整を繰り返し最適サイズを探します。
3. リトライとDLQ設定
失敗リトライ後、最大回数超えたらDLQへ送信し無限再試行を防ぎます。
resource "aws_sqs_queue" "standard_queue_dlq" {
name = "standard-queue-dlq"
visibility_timeout_seconds = 30
}
resource "aws_sqs_queue" "standard_queue" {
name = "standard-queue"
visibility_timeout_seconds = 30
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.standard_queue_dlq.arn
maxReceiveCount = 5 # 5回失敗でDLQへ
})
}
4. Lambdaコードの最適化
処理時間短縮でメッセージ滞留を減らし、スロットリングを抑制します。
5. FIFOキューの検討
直列処理を期待する場合はFIFOキューを使うとグループID単位で1件ずつ配信され、スロットリングを回避できます。
resource "aws_sqs_queue" "fifo_queue" {
name = "fifo-queue"
visibility_timeout_seconds = 30
fifo_queue = true
content_based_deduplication = true
deduplication_scope = "messageGroup"
fifo_throughput_limit = "perMessageGroupId"
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.fifo_queue_dlq.arn
maxReceiveCount = 5
})
}
まとめ
SQS標準キュー+Lambdaでは同時実行数上限やバッチ不整合でスロットリングが起きます。回避には同時実行数増加・バッチ調整・DLQ設定・コード最適化・FIFO検討が重要です。
株式会社BTMではエンジニアの採用をしております。ご興味がある方はぜひコチラをご覧ください。
-
SNS
-
投稿日
-
カテゴリー
BTM Useful