All Articles

Kinesisには気をつけろ

 CloudWatch Logs + Kinesis Data Steams + Lambdaでエラー検知とSlack通知を行う仕組みを作ってみたら、いい感じに動いてくれたのでそのまま運用してたのですが、それがアカンかった!

技術はしっかり理解して使いましょう!!

 全くもって当たり前の話なんですが、「水は低きに流れ、人の心もまた、低きに流れる。」もので取り敢えずは動いたからこれでいいやとなってしまうものですよね人ってw(直近で攻殻機動隊の2期を見たので引用したかっただけという)
では、このような運用してしまったがためにどのような天罰が来たのかと言うと、SlackへのLambdaエラーログの無限ループ通知が起こってしまいました。えっ!どういうこと!なんで同じ内容の通知が繰り返されるのって感じで凄く焦りましたよ。

 実は以前にSQS + Lambdaでシステムを作って運用していた経験があり、挙動的にも仕組み的にも似ていたのでKinesisも大丈夫でしょうという考えがあったのですが、SQSではループなんて起きたことがなかったので最初は対処の仕様がなく、原因にも心当たりがなかったので、取り敢えずはData Streamsを削除するという方法で対処しました。

 何故無限ループが起きてしまったのでしょうか?原因は、Kinesisからデータを受け取るLambda側で異常終了が発生していたからでした。では、異常終了すると何故無限ループとなるのか?それは、以下のようなKinesisの機能によるものでした。

  • Lambda側で異常終了が発生したデータに対しては、リトライ処理が走ります。このリトライ処理ですがKinesis内でのデータ保持期間だけ繰り返されます。そして、この保持期間ですがデフォルト設定では24時間となっているため、Lambdaで異常終了が続く限り一日中繰り返されます。
  • Kinesis Data StreamsはFIFOです。そのため、Lambdaで異常終了が発生するとデータ処理の順番を守るために、後続のデータ処理を一旦ストップし異常終了したデータを上記の仕組みでリトライ処理します。

    • ちなみに、Kinesisにはシャード単位でデータが処理される(シャード毎にLambdaが呼ばれる)ので異常終了したシャード以外のシャードでの処理がストップすることはありません。(検証はしていないですが)

 当たり前ですがリトライ処理では同じデータが使われるので、同じようにLambdaが異常終了するので無限ループの完成ということですね orz

挙動が似ているからと言って同じように動くと思うな!!

 SQSとKinesisですが、データのやり取りを円滑にしてくれる便利な奴という点では似ていますが、挙動はまるっきり違います。Kinesisが上記のような挙動に対してSQS(非同期トリガー)の場合はというと、

  • デフォルト設定ではFIFOではないため順番は保証されず、更には二重処理という問題が発生する可能性があります。
  • Lambdaで異常終了が発生した際には同じくリトライ処理が走りますが、デフォルトでは最大リトライ回数が2回に設定されてますので、最大リトライ回数に達するとDLQ(デッドレターキュー)を設定していない限りデータが削除されます。

 はい、全然違いますね〜と。ホント、実装当時の俺にもっと気をつけなさいよと言いたい気分です。なので、戒めの意味も込めてこの記事を書きました。

 最後までお付き合い頂きありがとうございます。今後もこのような(戒めではない)テック系の投稿ができればいいなと思っておりますので、その際はよろしくお願いします。