私たちは皆、特にAWS LAMBDA関数に関してサーバーレスを愛しています。
イベント駆動型、デカップリング、自動化、その他多くの理由で、Time AWS Lambdaがリリースされた理由は十分にあります。
しかし、親愛なる友人 LAMBDAが敵に変わってお金やダウンタイムを失う状況もあり、そうした時は意図しない再帰ループになります。
このブログでは、非常にシンプルながら強力な機能、すなわちaws lambdaとs3バケット間の再帰ループ検出についてお話しします。
動機
AWS のラムダ再帰ループとループ検出とは何ですか?
- ラムダ関数を起動する同じサービスやリソースとやり取りさせる場合、無限の再帰ループが発生するリスクがあります。
- 例えば、ラムダ関数がAmazon Simple Queue Service(SQS)キューにメッセージを送信し、SQSが同じ関数を再びトリガーすることがあります。
- これにより繰り返しの召喚のサイクルが生まれます。
それはあなたにとって何を意味するの?
- 意図しない再帰ループは、AWSアカウントに予期せぬ料金が発生し、 コストが急騰することがあります。
- さらに悪いことに、これらのループは Lambda 関数が急速に制御不能にスケールし、アカウントの利用可能な並行時間をすべて消費する原因となります。これは現在の機能だけでなく、他の重要なプロセスも停止させ、システム全体が圧倒され反応を失うこともあります。これは避けたい高額なミスです!
*これはAWSのラムダループ検出が解決しようとしている問題です。 *
このアップデートはあなたにとって何を意味するのでしょうか?
- これまでawsのラムダループ検出はAmazon SQSとAmazon SNSのみでサポートされており、 本日からs3もこのグループに参加しています。
ラムダがループを検出する方法
- LambdaはAWS X-Rayトレーシングヘッダーを用いて再帰ループを検出します。AWSサービスが対応した場合、イベントをLambdaに送信します
- イベントが関数を呼び出した回数を追跡するメタデータが含まれています。
- 同じイベントで関数が連続で約16回トリガーされた場合、Lambdaは自動的にさらなる呼び出しを停止し、あなたに警告を送ります。関数の他のトリガーはこの制限の影響を受けません。
詳しくはこちらでご覧いただけます。
実際に動かしてみよう。
- s3バケットを作成し、すべてデフォルトに保つ。

- ラムダ関数を作成して、ラムダが呼び出されるたびに s3 バケットにtxtファイルをアップロードします。 *** 注意:ラムダのデフォルトタイムアウトは3秒で、ファイルのアップロードにはそれ以上かかるため、タイムアウトを10秒に延長してください。そうしないとタイムアウトエラーが発生します。**
インポートBoto3
インポートOS
インポートランダム
インポート文字列
def lambda_handler(イベント、文脈):
# S3バケットを定義する
s3_bucket = 『your-s3-bucket-name』 # あなたのS3バケット名に置き換えてください
# ファイル名に付け加えるランダムな文字列を生成する
random_string = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
# ファイルの内容とキーを定義する(ランダムな文字列を追加して)
s3_key = f'your-file-{random_string}.txt' # S3 ファイルのキー(パス)
file_content = 「こんにちは、これはランダムな接尾辞付きのLambdaが作成したサンプルテキストファイルです!」
# ファイルを/tmpディレクトリにローカルで作成
local_file_path = '/tmp/sample_file.txt'
# ファイルにコンテンツを書き込む
ファイルとしてopen(local_file_path, 'w')を使った場合:
file.write(file_content)
# S3クライアントを初期化してください
s3 = boto3.client('s3')
# ファイルをS3にアップロード
試してみて:
s3.upload_file(local_file_path、s3_bucket、s3_key)
返す {
「statusCode」:200、
'body': f"ファイルが{s3_bucket}/{s3_key}に正常にアップロードされました"
}
例外はe:
返す {
「ステータスコード」:500、
'body': f"エラーアップロードファイル: {str(e)}"
}
- Lambda関数にトリガーを追加してS3トリガーとして。

- Lambda関数のIAM ロールにS3権限を追加してください。これらの権限により、awsのlambda関数がファイルをS3バケットにアップロードできるようになります
- ブログの簡潔さのために「AmazonS3FullAccess」管理ポリシーを添付します

- 任意のファイルをS3バケットにアップロードする。数秒後には、ファイルが自動的にバケットにアップロードされるのが見える。
- 他の友達ではラムダが正確に16回呼び出されるのがわかります。ラムダは正確に16個のファイルをアップロードし、その後ループ検出が作動します。

ループ検出のための通知を受け取る方法
- ドキュメントによると、再 帰ループ通知を受け取る方法は複数あります。例えば、AWS Health Dashboardの通知や、Lambdaが再 帰呼び出しを停止した後、このメールアラートを受け取るまでに最大3時間かかるメールアラートなどです。
- 届き次第ブログを更新します。(メール通知を追加)
- しかし、 最も速くて信頼できる方法は、Cloud Watch の指標を「RecursiveInvocationsDropped」の関数でチェックすることです。
CloudWatchメトリックのRecursiveInvocationsDroppedは、単一のリクエストチェーンで関数が約16回以上呼び出されたためにLambdaが停止した関数呼び出しの数を記録します。
ソリューションアーキテクトの視点から
- 再帰ループが存在することを知ることは重要ですが、そのループが起こらないようにどう応答するかを理解することはさらに重要です*:
- 再帰ループはラムダをスケールさせ、アカウントの利用可能な並行処理をすべて使用するため、 将来の呼び出しを制限するために可行性をゼロに設定してください。
- 最も単純な方法は、呼び出しを停止、つまり ラムダを呼び出しるトリガーを取り除くことです。
- 私のコードの再帰ループの原因となった設定/コードを修正してください。同じバケット名です。
- アーキテクチャ設計が要求する場合、 再帰ループにラムダを許可 するオプションもあります。
- ラムダループ検出はSQL、SNS、そして現在はS3でサポートされていることを理解することが非常に重要です。 Amazon DynamoDBなどのAWSサービスはループの一部であり、Lambdaは現在それを検出・停止できません。
このブログでは、S3でトリガーされて再帰ループが発生すると、アカウントのラムダがダウンタイムになるコスト削減やダウンタイムを回避する方法を紹介しました。
このアップデートでラムダがさらに良くなったという点も同意しますか?