どうも、SCSK齋藤です。
今回は、Amazon SQSから直接AWS Lambdaを呼び出す際に意識するポイントを3つ紹介します。(個人的につまづいたポイントです。。)
Lambda側でSQSからのメッセージを受信する権限が必要
とっても当たり前ですが、忘れがちなポイントです。
具体的には、受信以外にもいろいろな権限が必要になります。
ざっくりと必要な権限は下記です。
{ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Action" : [ "sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes", ], "Resource" : "*" } ] }
SQSを受信するだけでなく、受信した後にメッセージを削除する権限と、SQSの属性の読み取りを行う権限が必要です。
ここら辺の権限については、AWSのマネージドポリシーである「AWSLambdaSQSQueueExecutionRole」を付与すれば一発で権限を充足できます。
SQSの可視性タイムアウトはLambdaの関数タイムアウト時間の6倍にすること。
SQSのタイムアウト時間を、Lambdaの処理が終了する時間より短く設定すると、Lambda関数が処理中にも関わらず、メッセージがSQSで再度利用可能となり、別のLambda関数が同じメッセージを処理し始めるという事態になります。
Lambda関数の実行中にスロットリングが発生するなどもあり得るため、十分な実行時間を確保しておく必要がございます。
そこで、AWSのドキュメントではLambdaのタイムアウトの6倍を割り当てることを推奨しております。
SQSのリドライブポリシーでmaxReceiveCount属性を最低5にすること。
Lambdaの同時実行数が最大で、タイミング悪くLambdaが実行できない場合があります。
そういったケースの際に、すぐにDLQに転送するのではなく、合間を置いて再度Lambdaにメッセージを送信することで正しく処理を行うことが可能となります。
maxReceiveCountは、その再試行の回数を指定します。
AWSの推奨では、5以上とのことなのでそのように設定すると良いでしょう。
まとめ
今回は、SQS→Lambdaを呼び出す際に意識するポイントを勝手に3つ挙げました。
SQSもLambdaもいろいろな機能があるため、ユースケースによっては他にも意識することはあるかもしれませんので、引き続き勉強していきたいと思います。
今回あげたポイントは、CloudFormationなどでデプロイする際に、満たしていない場合はデプロイエラーになったりするポイントなので、意識してみることをお勧めします!