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 のスループットが向上します。バッチごとに処理するレコード数が少ないと、ストリームの処理が遅くなります。
一方、バッチあたりのレコード数が多い場合は、関数の実行時間が長くなる可能性があります。そのため、複数の値を使用してテストし、ユースケースに最適な値を見つけてください。
関数のランタイムの継続時間がイベント内のレコード数に依存しない場合、関数のバッチサイズを増やすと、関数のイテレーターの経過時間が短くなります。
関連情報
Amazon DynamoDB で AWS Lambda を使用する
Lambda を使用して、Amazon SES E メールの Amazon SNS 通知を DynamoDB に保存するにはどうすればよいですか?