はじめに
AWS Lambda関数は、処理が失敗した際に 自動的に再試行(再起問い合わせ) される場合があります。
この再試行の仕組みは、Lambdaをどのイベントソースから実行するかによって異なります。
今回の問題をきっかけに、Lambda関数の再試行について体系的に整理する必要があると感じたため、この記事でまとめていきます。
困っていたこと
今月は特にAWSを使用する作業をしていなかったのですが、気づいたら CloudWatchの課金額が増えている ことが判明しました。
調査したところ、現在Lambda関数が常にエラーを発生しており、そのたびにCloudWatchLogsにログが記録され、課金が発生していることがわかりました。
原因を特定したところ、DatadogとAWSアカウントのインテグレーション連携時に作成したLambda関数が、バックグラウンドで70回以上実行されていることが確認できました。
今回はこの失敗を機に、Lambda関数の再試行の仕組みを正しく理解する必要があると感じたため、記事としてまとめていきます。
Lambda関数の再起問い合わせ(再試行)について
AWS Lambdaでは、関数の実行が失敗した際に 自動的に再試行(再起問い合わせ) が行われることがあります。
引用画像:https://dev.classmethod.jp/articles/detecting-and-stopping-recursive-loops-in-aws-lambda-functions/
再試行の回数や動作は、Lambda関数の実行方法(同期・非同期・ストリームベース・SQS)によって異なります。
Lambdaの再試行(再起問い合わせ)が発生するケース
Lambdaは、主に以下のイベントソースからトリガーされる場合に再試行されます。
同期実行(Synchronous Invocation)
- 対象: API Gateway、AWS SDK、CLI など
-
動作:
- 失敗しても自動的に再試行されない
- 呼び出し元(クライアントやAPI Gatewayなど)がエラーを受け取り、手動で再試行する必要がある
対策
- エラー処理をLambda関数内に実装する(例:エラーハンドリングやリトライ処理)
- API Gateway側で再試行ロジックを追加する
非同期実行(Asynchronous Invocation)
- 対象: SNS、S3、EventBridge など
-
動作:
- 最大2回まで自動再試行
- 失敗すると1分後に1回目の再試行、さらに2分後に2回目の再試行
- 3回失敗するとDead Letter Queue(DLQ)やLambdaのエラーメトリクスに記録
対策
- エラー処理をLambda関数内に実装する
- DLQを設定し、エラー発生時の対応を明確にする
イベントストリーム(Kinesis, DynamoDB Streams)
- 対象: Kinesis Data Streams、DynamoDB Streams
-
動作:
- 処理が失敗すると、一定の間隔で最大2回の再試行
- それでも失敗すると、データのシャードが停止し、新しいデータも処理されなくなる
対策
- エラーハンドリングを強化し、リトライ可能なエラーとそうでないエラーを区別
- データをDLQやS3に保存し、失敗したデータを後から再処理できるようにする
SQS(Amazon Simple Queue Service)
- 対象: SQSキュー
-
動作:
- メッセージの処理が失敗すると、自動的に再試行
- 既定の可視性タイムアウト(visibility timeout)が経過すると、再びメッセージがLambdaに渡される
- 最大回数を超えると、DLQ(Dead Letter Queue)へ移動
対策
- SQSの最大受信回数(MaxReceiveCount)を適切に設定
- Lambdaの実行時間を調整し、タイムアウトを防ぐ
- DLQを設定し、失敗したメッセージを確認する
Lambdaの処理が失敗すると、イベントソースごとに異なる再試行ルールが適用されます。
適切なエラーハンドリングとDLQの設定を行い、信頼性の高いシステムを構築しましょう。
今回の一時回避策
私の環境では、今回AWSアカウントとDatadogという海外のクラウドに特化したサードパーティ製品を紐付けるために、このLambda関数を作成していました。
しかしながら、現状設定がうまくいっていないこともあり、一度Lambda関数自体を削除し、不要なCloudWatchLogsも削除することで課金を抑えることにしました。
まとめ
今回は、私自身も原因調査をする中で初めて遭遇する事象だったため、正直焦りました。しかしながら、早期に発見できたことで、大幅なコスト増加を防ぐことができました。
やはりこのような仕組みを事前に理解しておくことの重要性を改めて実感しました。
今回の失敗談が、誰かのコスト削減の支えになれば幸いです。