Amazon DynamoDB streams で Lambda IteratorAge メトリクスが増加しているのはなぜですか?

最終更新日: 2022 年 9 月 12 日

Amazon DynamoDB ストリームからレコードを消費すると、AWS Lambda IteratorAge メトリクスにスパイクが表示されます。関数のイテレータの経過時間が増加するのはなぜですか? また、それを減らすにはどうすればよいですか?

簡単な説明

Lambda IteratorAge メトリクスは、レコードが DynamoDB ストリームに追加されてから、関数がそのレコードを処理するまでのレイテンシーを測定します。IteratorAge が増加すると、これは Lambda が DynamoDB ストリームに書き込まれるレコードを効率的に処理しないことを意味します。

IteratorAge が増加する主な理由は次のとおりです。

  • 呼び出しエラー
  • スロットリングの発生
  • Lambda のスループットが低い

解決方法

呼び出しエラー

Lambda は、レコードのバッチを順番に処理し、エラー時に再試行するように設計されています。そのため、関数が呼び出されるたびに関数がエラーを返す場合、Lambda は再試行を続けます。これは、レコードが期限切れになるか、イベントソースマッピングで設定した最大有効期間を超えるまで実行されます。DynamoDB ストリームの保持期間は 24 です。Lambda は、レコードの有効期限が切れるまで最大 1 日間再試行を続け、その後レコードの次のバッチに進みます。

Lambda errors メトリクスを調べて、呼び出しエラーが IteratorAge スパイクの根本原因であるかどうかを確認します。原因である場合は、Lambda ログを確認してエラーをデバッグし、コードを変更します。エラーを処理するときは、必ず try-catch ステートメントをコードに含めてください。

イベントソースマッピング設定には、IteratorAge のスパイクを防ぐのに役立つ 3 つのパラメータがあります。

  • 再試行回数: 関数がエラーを返すまでに Lambda が再試行する最大回数。
  • レコードの最大有効期間 - Lambda が関数に送信するレコードの最大有効期間。これは、古すぎるレコードを破棄するのに役立ちます。
  • エラー時にバッチを分割 - 関数がエラーを返した場合、再試行する前にバッチを 2 つに分割します。小さいバッチで再試行すると、不正なレコードが分離され、タイムアウトの問題を回避できます。注意: バッチを分割しても、再試行クォータにはカウントされません。

破棄されたイベントを保持するには、失敗したバッチの詳細を Amazon Simple Queue Service (Amazon SQS) キューに送信するようにイベントソースマッピングを設定します。または、Amazon Simple Notification Service (Amazon SNS) トピックに詳細を送信するようにイベントソースマッピングを設定します。これを行うには、OnFailure 送信先パラメータを使用します。

スロットリングの発生

イベントレコードは順番に読み取られるため、現在の呼び出しがスロットリングされている場合、関数は後のレコードに進むことができません。

DynamoDB ストリームを使用する場合、同じストリームシャードに 3 つ以上のコンシューマを設定しないでください。シャードごとにリーダーが 3 つ以上ある場合は、スロットリングが発生する可能性があります。1 つのストリームシャードに 3 つ以上のリーダーが必要な場合は、ファンアウトパターンを使用します。ストリームからレコードを消費するように Lambda 関数を設定し、他のダウンストリーム Lambda 関数または Amazon Kinesis ストリームに転送します。

Lambda 側では、同時実行数の制限を使用してスロットリングを防止します。

Lambda スループット

ランタイムの継続時間

Lambda 関数の Duration メトリクスが高い場合は、関数のスループットが低下し、IteratorAge が増加します。

関数のランタイムの継続時間を短縮するには、次のいずれかまたは両方を実行します。

1.    関数に割り当てられるメモリ量を増やします

2.    レコードの処理にかかる時間を短縮するために、関数コードを最適化します。

同時 Lambda 実行

Lambda の同時実行の最大数は次のように計算されます。

同時実行 = シャード数 x シャードあたりの同時バッチ (並列化係数)

  • シャードの数 - DynamoDB ストリームでは、テーブルのパーティション数とストリームシャード数の間に 1<>1 のマッピングがあります。パーティションの数は、テーブルのサイズとスループットによって決まります。テーブルの各パーティションは、最大 3,000 の読み取りリクエスト単位または 1,000 の書き込みリクエスト単位、またはその両方を線形的に組み合わせることができます。そのため、同時実行性を高めるには、テーブルのプロビジョニングされたキャパシティを増やしてシャードの数を増やします。
  • シャードあたりの同時バッチ (並列化係数) - イベントソースマッピングのシャードあたりの同時バッチ数を構成できます。デフォルトは 1 であり、10 まで増やすことができます。

例えば、テーブルに 10 のパーティションがあり、[シャードあたりの同時バッチ] が 5 に設定されている場合、最大 50 の同時実行が可能です。

注意:アイテムレベルの変更をいつでも正しい順序で処理するために、同じパーティションキーを持つアイテムは同じバッチに移動します。そのため、テーブルパーティションキーのカーディナリティが高く、トラフィックがホットキーを生成しないことを確認してください。例えば、シャードあたりの同時バッチ数を 10 に設定し、書き込みトラフィックが 1 つのパーティションキーをターゲットにしている場合、シャードごとに 1 つの同時実行のみが可能です。

バッチサイズ

バッチサイズの値を調整すると、Lambda のスループットが向上します。バッチごとに処理するレコード数が少ないと、ストリームの処理が遅くなります。

一方、バッチあたりのレコード数が多い場合は、関数の実行時間が長くなる可能性があります。そのため、複数の値を使用してテストし、ユースケースに最適な値を見つけてください。

関数のランタイムの継続時間がイベント内のレコード数に依存しない場合、関数のバッチサイズを増やすと、関数のイテレーターの経過時間が短くなります。