0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【小ネタ/Tips】S3不要の喜びに潜む罠!AWS Lambdaで「ゾンビ・リトライ」を意図的に引き起こす方法 〜非同期ペイロード1MB拡大〜

0
Posted at

【導入文】
こんにちは。社内システムのクラウド化を支援している「僕」です。
ハードウェアを愛する半導体エンジニアの「妻」にAWSを語るこのシリーズ。今回は、最近アップデートされたばかりのLambdaの新機能と、そこに潜むちょっと怖い「罠」について妻と検証した日の会話をお届けします。


1. 【プロローグ】1MBの荷物を直接投げ込める魔法

僕: 「ねえ聞いて! ついにAWS Lambdaの『非同期呼び出し』で、一度に送れるデータ(ペイロード)の上限が、256KBから1MBに拡張されたんだ!」

妻: 「へえ。外部ストレージ(S3)をわざわざ経由しなくても、1MBのまとまったデータを直接データバスに流し込めるようになったのね。L1キャッシュが増量されたみたいで便利じゃない。」

僕: 「そうそう! これで、ちょっとした画像データや重いJSONファイルなら、直接Lambdaに投げ込めるようになったんだよ!」

妻: 「でもちょっと待って。『非同期(投げっぱなし)』なんでしょ? 工場の天井を走る自動搬送台車(OHT)にウェハーをポンと乗せて『あとはよろしく!』って送り出した後、受け取り側の装置がエラーで止まってたら、そのデータはどうなるの?」

僕: 「えっ? 失敗したら普通にポイッとエラーが返ってきて終わりじゃないの?」

妻: 「本当に? クラウドの『投げっぱなし』ってそんなに潔いのかしら。ちょっと検証してみましょ。」

2. 【Tipsのタネ明かし】非同期呼び出しの「自動再配達」機能

僕: 「……ということで、検証の前に種明かしを。Lambdaには『同期(その場で結果を待つ)』と『非同期(AWS側に処理を預けて結果を待たない)』の2種類の呼び出し方があるんだ。」

妻: 「同期回路と非同期回路みたいなものね。」

僕: 「非同期呼び出しは、イベント駆動でよく使われるんだけど、実はこの裏側には**『処理がエラーになった場合、AWS側が勝手に再実行(リトライ)してくれる』**という強力な仕組みが隠れてるんだ。」

3. 【実践Tips】恐怖の「ゾンビ・リトライ」を発生させる手順

僕: 「では、この親切な機能が『罠』に変わる瞬間を、あえて意図的に引き起こしてみるよ。」

  1. 絶対失敗するLambdaを作る
    Pythonなどで、呼び出されたら必ず raise Exception("わざとエラー") を起こすような、バグ入りのLambda関数を作成する。
  2. 1MBギリギリのデータを非同期で送りつける
    AWS CLIを使って、ダミーのテキストデータ(約1MB)を Invoke コマンドの --invocation-type Event(非同期モード)でこの関数に送信!
  3. ログの観察(罠の発動)

僕: 「ほら、コマンドの実行自体は『受け付けました(Status 202)』って即座に返ってきたよ。」

妻: 「ステータス202って、単に手前のバッファメモリが『データ受け取ったよ』って言ってるだけでしょ? メインのプロセッサが処理したわけじゃないわ。」

僕: 「その通り。で、数分後にCloudWatch Logs(実行記録)を確認すると……うわっ! 自分が1回しか実行していないはずのLambdaが、エラーを吐きながら何度も何度も勝手に再実行されてる!」

4. 【解説と解決策】なぜ勝手に動き続けるのか?

僕: 「なにこれ、ゾンビみたいに何度も蘇ってエラーを吐き続けてるよ!」

妻: 「バッファに受け取った後、どういう挙動になってるの?」

僕: 「AWSのドキュメントをよく読んだら、非同期で受け取ったデータはAWS内部のキュー(待ち行列)に一度入る仕様なんだ。で、処理に失敗すると『あれ? ネットワークのノイズかなんかで、たまたま失敗したのかも』と思って、時間を空けて 最大2回(合計3回)まで自動的に再配達(リトライ) しようとするんだって。」

妻: 「なるほど、通信プロトコルの自動再送要求(ARQ)と同じね。親切な設計だけど、今回みたいなプログラムのバグ(根本的な欠陥)の場合は、何度再送してもエラーになるのは当たり前じゃない。もしこれが『重い処理』を伴う1MBのデータだったら、無駄なリトライのたびにLambdaのクロックサイクル(実行時間=コスト)を食いつぶすことになるわよ。」

僕: 「確かに! 宅配便のお兄さんが、留守の家に何度も重い荷物を運んできてくれるようなものだけど、そもそも住所(プログラム)が間違ってたら無駄なコストになっちゃうね。」

解決策のTips:
このゾンビ化を防ぐには、非同期呼び出しの設定で「最大再試行回数」を0にするか、デッドレターキュー(DLQ)やOn-Failureの送信先(エラー用の通知先) を必ず設定しましょう。

僕: 「DLQっていう設定をしておけば、『再配達に失敗した荷物(エラーになったデータ)』を、いつまでも処理し続けずに、別の場所(SQSやSNSなど)に安全に退避させることができるんだ。」

妻: 「つまり、処理できなかった不良品のデータをいつまでもラインに流し込まずに、別の『リジェクトボックス』に弾き出すってことね。歩留まり管理とエラーハンドリングの基本じゃない。AWSもちゃんと考えてるわね。」

5. 【お片付け】無駄な実行課金に注意

僕: 「非同期の『投げっぱなし』の裏には、AWSの執念深い再配達システムがあったんだね……。」

妻: 「データバスの幅が1MBに広がって便利になった分、エラー時の影響も大きくなるわ。非同期を使うなら、そのDLQ? っていうリジェクトボックスの設定は絶対に鉄則よ。」

僕: 「勉強になった! じゃあ検証も終わったし、ご飯にしようか。」

妻: 「ちょっと待って。さっきの『絶対失敗するLambda』、ちゃんと削除した? 放置してると、もし誰かが間違って非同期で呼び出したら、また無駄にリトライして我が家のOpEx(お小遣い)から課金されるわよ。」

僕: 「おっと危ない! すぐに関数を削除(Delete)してきます!」

【結びの文】
ペイロード枠が1MBに拡大し、S3を経由せず直接データを送り込めるようになってますます便利になったLambdaの非同期呼び出し。しかし、ハードウェアエンジニアの妻が指摘した通り、エラー時の「再配達(リトライ)」の仕様を理解し、正しいエラー退避ルート(DLQ)とお片付けを忘れないように十分ご注意ください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?