ストリームLambdaで処理遅延メトリクスが取得可能になりました

AmazonLambda

DynamoDBやKinesisに投入されたデータをAWS Lambdaでストリーム処理されている方は多いと思います。

これまでストリーム処理の遅延状況をモニタリングするにはDynamoDB/Kinesis側のメトリクスしか提供されていませんでした。 今回のアップデートにより、AWS Lambda側のメトリクスも提供されるようになりました。

何が嬉しいの?

KinesisストリームにはGetRecords.IteratorAgeMillisecondsというメトリクスが存在します。このメトリクスは現在の時刻と、GetRecords 呼び出しの最後のレコードがストリームに書き込まれた時刻の差です。ストリームに書き込まれた直後にGetRecordsが呼び出されていれば0に近く、遅延が発生していれば、より大きい値になります。

ストリームにLambdaが一つだけぶら下がっている場合、ストリームから見える遅延とLambdaワーカーの遅延は一致します。

ストリームに複数のLambdaがぶら下がっていた場合、ストリームデータを滞りなく処理し続けるワーカーが少なくとも一つあれば、このメトリクスは0に近い値を指し示します。遅延しているLambdaワーカーが存在していても、ストリーム側のメトリクスを見ているだけでは一部のLambdaワーカーで遅延が発生していることに気づきません。

今回のアップデートにより、ワーカー単位で遅延状況をモニタリング出来るようになりました。

ストリーム処理遅延を発生させてありがたみを享受してみる

先程説明したようなシナリオを実際に発生させてメトリクスを確認しましょう。

KinesisストリームにLambdaが2つぶら下がっており、片方(fast worker)はストリームデータを遅延なく処理し、もう片方(slow worker)は遅延が発生しているとします。

lambda_iterator_age_architecture

しばらく放置したあとのメトリクスが以下です。

lambda_iterator_age

  • Kinesisストリームのメトリクス(GetRecords.IteratorAgeMilliseconds)
  • 遅延が発生していないLambda(fast woker)のメトリクス(Iterator Age)

はほぼ同じ値を指し示し

  • 遅延が発生しているLambda(slow worker)のメトリクス(Iterator Age)

は遅延しているため大きな値を示しています。

今後は各LambdaのIterator Ageメトリクスをモニタリングすれば、Lambda単位で遅延状況をすぐに気づけるようになります。

注意

Kinesis StreamsにはGetRecords.IteratorAgeというDeprecatedなメトリクスも存在し、このメトリクスの単位は秒です。 LambdaのメトリクスIterator Age単位はミリ秒であることに注意して下さい。

遅延発生方法について

Lamba 関数

検証用Lambdaには5秒スリープするだけのシンプルな関数を用意しました。

def lambda_handler(event, context):
    import time
    time.sleep(5)

遅延有り・無しの2つのLambda関数の違いは、LambdaがストリームデータをPULLした時のバッチサイズだけです。 処理が遅いほうは1,早いほうは100としました。 遅いLambda関数は、一度に1レコードしか処理できず、処理に5秒かかるため、単純計算で0.2レコード/秒よりも早いペースでストリームにデータを送り続ければ、遅延が発生することになります。

データ投入スクリプト

今回はKinesisストリームに0.5秒ごとに1レコードデータ投入しました。

#!/bin/bash
while :
do
  aws kinesis put-record --stream-name iterator_age --data 1 --partition-key 1
  sleep 0.5
done

まとめ

LambdaにIterator Ageメトリクスが追加されたことにより、ストリームのワーカー単位で処理遅延を検出出来るようになりました。 Kinesis/DynamoDBストリームでFan Out処理をしている方は、このメトリクスをモニタリングするようにしましょう。

参照

AWS Cloud Roadshow 2017 福岡