今回は、Insights系のものを使って、救われた話しと痛い目にあった話しをしたいと思います。
特に、痛い目に合うだけではなく、ちゃんと高額の請求がくる可能性があるので、有効化する前に一度この記事を読んでくれると嬉しいです。
Lambda Insightsに救われた話し
事の発端は、Lambdaでかなり無茶な並列処理を書いていた時のことです。
ユーザーIDの下一桁(a~z, 0~9なので36分割)ごとに、ファイル × 24時間 × 複数日 というかなりの数のファイルを同時に開いて処理するバッチ的なLambdaを動かしていました。
今考えると、なんでそんなことをやったのか、、と反省してます。
ここで謎のバグに遭遇します。
「あれ、、実行するたびに、結果が微妙にずれる!!
」
エラーで完全に落ちるわけではなく、何のエラーも出てなかったです。
しかも、開いているファイル数が心配でログも組み込んではいたものの、ログにもなにも出てなかったです。
コードを見直しても原因が分からず、悩んでいたところ、同期にLambda Insightsをお勧めしてもらいました。(神様....)
ダッシュボードを見て一発で原因が判明しました。
原因は「開いているファイル数の上限(ファイルディスクリプタ制限)の超過」でした。
Lambdaの実行環境は、デフォルトで開けるファイル数の上限が1024程度に設定されています。
同時実行で大量のファイルを一気に開く実装にしていたため、Lambdaのコンテナ環境の制限値ギリギリを行ったり来たりして、一部のファイル読み込みがサイレントに失敗していたんです。(エラー出してくれると嬉しいのですが、、)
「Insightsすげえ!中身の挙動が丸裸じゃん!」
そしてこの成功体験が、数ヶ月後の失敗の伏線になります。
本番環境 × AWS Batch × Container Insights = 絶望の請求書
Lambdaでの成功体験から「Insights系の機能は神。本番のトラブルシューティングにも常備しておくべき」とすっかり思い込んでいました。
そこで本番のAWS Batch(Fargate)にもContainer Insightsを有効化しておきました。
今回は本番データということもあり、AWS Batchのジョブを36並列で一気に起動してガッツリ処理を回しました。
ジョブ自体は無事に成功し、「やっぱり並列処理は速くていいなー」と平和に終わった、、はずでした。
後日。
AWSのBillingダッシュボードを何気なく開いた私は、謎の課金グラフの跳ね上がりに目を疑いました。
普段は月に数ドル程度のCloudWatch代が、その月だけ280ドルまで跳ね上がっていたのです。
円換算すると4万円超えでした....。
「CloudWatchのコストがあり得ないくらい高い……!!!」
調べてみると、犯人は間違いなくContainer Insightsでした。
なぜこんなに高くなったのか?
CloudWatchのカスタムメトリクスは、1メトリクスあたり月0.3ドル前後の課金です(リージョンや利用量で変動します)。
一見安く見えるこの単価が、条件次第で一瞬で積み上がります。
Container InsightsをFargateで有効化すると、CPUやメモリ、ネットワークなどの詳細なカスタムメトリクスがタスク(コンテナ)ごとに大量に生成されます。
私の場合、以下の悪条件が見事に重なっていました。
バッチ処理であること(常駐タスクではなく、起動と終了を繰り返すため、新しいタスクIDのメトリクスが無限に増える)
36という高い同時実行数(全タスクが一斉にカスタムメトリクスをCloudWatchに吐き出し続ける)
「便利だから」という理由だけで、同時実行数の多いバッチ環境にContainer Insightsを常時ONで仕込むのは、文字通り札束を燃やしてメトリクスを買っているのと同じ状態だったわけです。
まとめ
これらの苦労(と高い勉強代)から得た教訓です。
Insightsはトラブルシューティングには最強の武器です。
OSレベルの挙動(ファイルオープン数など)が見えるのは本当に助かります。
ただし、「同時実行数が多い環境(大量のLambdaやBatchタスク)」で常時ONにするのは絶対にやめるべき。(特に、それが本番環境なら、、)
基本はOFFにしておき、「どうしても原因不明のバグが起きた時だけ、期間を決めてONにする(デバッグ用途)」という使い方がベストだと思います。
AWSのマネージドな監視ツールは本当に優秀ですが、裏側でどれだけのメトリクスが生成され、それにいくら課金されるのかは、ボタンを押す前に一度立ち止まって計算(あるいは警戒)しないと痛い目を見ます。
同じような「CloudWatch破産」を迎える人が少しでも減ることを祈っています。