AWS Lambda が Amazon DynamoDB Streams からのレコードを消費しているとき、Lambda の IteratorAge メトリックスが急増しているのがわかります。
簡単な説明
Lambda IteratorAge メトリックスは、レコードが DynamoDB ストリームに追加されてから、関数がそのレコードを処理するまでのレイテンシーを測定します。IteratorAge の増加は、Lambda が DynamoDB ストリームに書き込まれるレコードを効率的に処理していないことを意味します。
IteratorAge の増加には以下の理由が考えられます。
- 呼び出しエラー
- スロットル発生
- Lambda スループットの低下
解決方法
呼び出しエラー
Lambda は、レコードのバッチを順番に処理し、エラー発生時には再試行するように設計されています。関数が呼び出されるたびにエラーが返される場合、レコードの有効期限が切れるまでは、Lambda による再試行が継続します。または、イベントソースマッピングで設定した最大有効期間を超えるまでは、Lambda による再試行が継続します。DynamoDB ストリームの保持期間は 24 時間です。Lambda による再試行は最大 1 日間継続します。その後、次のレコードバッチに進みます。
呼び出しエラーが IteratorAge の急増の根本原因であるかどうかを確認するには、Lambda エラーメトリックスを確認します。呼び出しエラーが原因である場合は、Lambda ログを確認してエラーをデバッグし、コードを変更してください。エラーを処理するときは、必ず try-catch ステートメントをコードに追加してください。
イベントソースマッピングの設定には、IteratorAge の急増を防ぐのに役立つ以下の 3 つのパラメータがあります。
- **再試行回数:**このパラメータは、関数がエラーを返したときに、Lambda が再試行する最大回数を設定します。
- **レコードの最大有効期間:**このパラメータは、Lambda が関数に送信するレコードの最大有効期間を設定します。このパラメータを使用すると、古すぎるレコードを破棄するのに役立ちます。
- **エラー発生時にバッチを分割:**このパラメータは、小さいバッチで再試行して不良レコードを分離し、タイムアウトの問題を回避するのに役立ちます。関数がエラーを返す場合は、バッチを分割してから再試行します。
注: バッチの分割は再試行クォータに対してはカウントされません。
破棄されたイベントを保持するには、失敗したバッチの詳細を Amazon Simple Queue Service (Amazon SQS) キューに送信するようにイベントソースマッピングを設定します。または、詳細を Amazon Simple Notification Service (Amazon SNS) トピックに送信するようにイベントソースマッピングを設定します。これを行うには、障害発生時の宛先パラメータを使用します。
スロットル発生
イベントレコードは順番に読み込まれるため、現在の呼び出しがスロットリングされている場合、Lambda 関数は次のレコードに進めません。
DynamoDB ストリームを使用するときは、同じストリームシャードに設定するのは 2 つのコンシューマーまでにしてください。1 つのシャードに 3 つ以上のリーダーがある場合、関数がスロットリングされる可能性があります。詳細については、「ストリームの読み込みと処理」をご覧ください。
1 つのストリームシャードに 3 台以上のリーダーが必要な場合は、ファンアウトパターンを使用します。ストリームからレコードを使用するように Lambda 関数を設定し、それを他のダウンストリームの Lambda 関数または Amazon Kinesis ストリームに転送します。Lambda については、同時実行制限を使用してスロットリングを防止します。
Lambda スループット
実行時間
Lambda 関数の Duration メトリックスが高いと、関数のスループットは低下し、IteratorAge は増加します。
関数の実行時間を短縮するには、次の方法のいずれかまたは両方を使用します。
Lambda の同時実行
Lambdaの同時実行の最大数は次のように計算されます。
同時実行 = シャード数 x シャードあたりの同時バッチ (並列化係数)
- **シャードの数:**DynamoDB ストリームでは、テーブルのパーティション数とストリームシャードの数が 1 対 1 で対応しています。テーブルのサイズとテーブルのスループットによって、パーティションの数が決まります。テーブルの各パーティションは、最大 3,000 の読み取りリクエストユニットまたは 1,000 の書き込みリクエストユニット、または両者の組み合わせを、それぞれのユニット数の最大ユニット数に対する割合の合計が 100% を越えない範囲において処理できます。同時実行を増やすには、テーブルのプロビジョニング容量を増やしてシャードの数を増やします。
- **シャードあたりの同時バッチ (並列化係数):**イベントソースマッピングでは、シャードあたりの同時バッチの数を設定できます。デフォルトは 1 で、最大 10 まで増やすことができます。
たとえば、テーブルに 10 個のパーティションがあり、シャードあたりの同時バッチが 5 に設定されている場合、最大 50 個の同時実行が可能です。
**注:**アイテムレベルの変更をいつでも正しい順序で処理するために、同じパーティションキーを持つアイテムは同じバッチに移動します。テーブルパーティションキーのカーディナリティが高く、トラフィックによってホットキーが生成されないことを確認してください。たとえば、シャードあたりの同時バッチ数の値を 10 に設定し、書き込みトラフィックが 1 つのパーティションキーを対象としている場合、シャード 1 つにつき同時実行は 1 つのみです。
バッチサイズ
Lambda スループットを向上させるには、バッチサイズの値を調整します。バッチごとに処理するレコード数が少ない場合、ストリームの処理速度は遅くなります。バッチあたりのレコード数が多い場合、関数の実行時間が長くなる可能性があります。ユースケースに最適な値を見つけるには、バッチサイズを複数の値でテストするのがベストプラクティスです。
関数の実行時間がイベント内のレコード数に依存しない場合は、関数のバッチサイズを大きくすると、関数のイテレータの有効期間が短くなります。
関連情報
Amazon DynamoDB での AWSLambda の使用