Kinesis Data StreamsのレコードをLambda関数で処理するアプリケーションについて、CloudWatchメトリクスを分析することで以下の様な用途に役立てることができます。
- アプリケーションの動作におけるエラーの兆候を見つける
- 入力されるデータ量が増えるに従ってKinesis Data Streamのシャードを拡張するといった例にみられるように、リソースの拡張が必要な兆候を見つける
- AWSサービス利用料が適正であるかを分析し、コスト削減につなげる
上記の様な目的でCloudWatchメトリクスを分析した経験から、Kinesis Data StreamsとLambda関数のCloudWatchメトリクスをどのように分析するのかをまとめてみたいと思います。
Lambda関数のCloudWatchメトリクス
ここでは、Kinesis Data Streamsのレコードを処理するLambda関数に関連するCloudWatchメトリクスの中でコスト、エラー検知、拡張性の観点で注目すべきメトリクスを取り上げたいと思います。
Invocations
InvocationsはLambda関数の起動回数を示すメトリクスになります。Kinesis Data StreamsからLambda関数がレコードを読み込む場合、デフォルトで1秒おきにレコードを読み込むため、100シャードのストリームの場合、各シャード毎に1秒間隔で1回Lambda関数が起動されますので、合計して1秒間に100回のLambda関数が起動されることになります。ただし、1回のLambda関数の起動でシャードから読み込んだレコードを処理するのに1秒以上かかる可能性があります。この場合は、処理完了後にLambda関数が起動されますので、Lambda関数の起動は1秒間隔でないケースがあります。この場合は、秒間あたりのLambda関数の起動回数も減少していきます。
Duration
Invocationのメトリクスで説明しましたように各シャードごとに1秒ごとにLambda関数が1回起動されますが、Durationは起動されたLambda関数内での処理時間になります。1回のLambda関数の起動でシャードから読み込んだレコードの処理に時間がかかる場合にはDurationも長くなります。レコードの処理内容が複雑で処理に時間がかかるような場合はDurationが延びていくことになります。
Concurrent executions
Concurrent executionsは同時実行しているLambda関数の数になります。Kinesis Data Streamsで複数のシャードを使用する場合、1つのシャードに投入されるレコードを処理するLambda関数の数を指定できます1。シャード数をM、シャードあたりのLambda関数をNとした場合、全てのシャードを処理するLambda関数の同時並行数(Concurrent executions)は最大でMxNになります。投入されるレコードのPartition Keyを適切に設定しないと、Kinesis Data Streamsの各シャード及びシャードに割り当てられた複数のLambda関数にバランスよくレコードが振り分けられません2。Concurrent executionsの数値がシャード数やシャードあたりのLambda関数の設定に比較して小さい場合にはPartition Keyの設定によりレコードの振り分けがうまくいっていないことも一因として考えられます。
IteratorAge
シャードにレコードが投入されてからその後にLambda関数によりそのレコードが取得される(読み込まれる)までの所要時間になります。シャードからレコードを読み込んだ後にLambda関数の処理が遅延した場合、その処理が終わるまでLambda関数によりシャード内のレコードは読み取られないため、シャード内のレコードがLambda関数に読み込まれるまでの所要時間(IteratorAge)が長くなります。逆に言えばIteratorAgeが長くなっている場合は何等かの理由でLambda関数の処理が遅延している(Lambda関数のdurationが延びている)ことになります。
Error count and success rate
Lambda関数またはLambda関数が稼働するLambda runtime内で想定外のエラーが発生している場合はError countのメトリクスにカウントされます。Error countがカウントされている場合はLambda関数内に実装したユーザーコードのエラー処理で拾えていないような想定外のエラーが発生していることになります。Error countがカウントされている場合はLambda関数が出力するCloudWatch Logsを解析することによりエラー内容の詳細に解析して下さい。
各メトリクスの活用方法
コスト観点
Lambdaの料金はInvocationsの回数とDurationの長さにより課金されます。運用の中でLambda関数の単位時間当たりのInvocationsの回数の合計と平均Durationが上昇してきた場合はLambda関数の課金が増えてきている兆候になります。
エラー確認の観点
Lambda関数またはLambda runtimeでの想定外のエラーを検知する場合にはError countのメトリクスに対してCloudWatchアラームを設定することで検知することができます。
拡張性の観点
Lambda関数の処理時間(Duration)が長くなっている、Kinesis Data Streamの投入されたレコードが処理されるまでの時間(IteratorAge)が長くなってきている、Lambda関数の同時実行数(Concurrent Executions)が増加してきているといった兆候が見られる場合にはKinesis Data Streamのシャードの数を増やすまたはシャードあたりのLambda関数の数を増やす等、パラメーターチューニングによる拡張を考慮する必要があります。
拡張性の観点やコスト削減の観点ではCloudWatchメトリクスの値を参考にどのようにパラメーターをチューニングするかは別の記事でまとめてみたいと思います。
-
[こちらのマニュアル][link1]の「シャードごとの同時実行バッチ」のパラメーターを参考にしてください。
[link1]:https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-kinesis.html#services-kinesis-eventsourcemapping ↩ -
Partition Keyによるシャード及びシャードに割り当てられたLambda関数への振り分けルールについては[こちらの記事][link2]を参考にしてください。
[link2]:https://qiita.com/sabmeua/items/7fec5b8dd3415c5733cb ↩