べき等性 - AWS Lambda

べき等性

耐久関数は、実行名から実行を開始するための組み込みのべき等性を提供します。実行名を指定すると、Lambda はそれを使用して重複する実行を防ぎ、呼び出しリクエストの安全な再試行を可能にします。ステップにはデフォルトで at-least-once の実行セマンティクスがあります。リプレイ中、SDK は完了したステップを再実行せずにチェックポイントされた結果を返しますが、完了前に発生する可能性がある再試行を処理できるように、ビジネスロジックはべき等性である必要があります。

注記

Lambda イベントソースマッピング (ESM) は、起動時のべき等性をサポートしていません。したがって、各呼び出し (再試行を含む) は新しい耐久性のある実行を開始します。イベントソースマッピングを使用してべき等性の実行を確実に行うには、の Powertools for AWS Lambda などの関数コードにべき等性ロジックを実装するか、通常の Lambda 関数をプロキシ (ディスパッチャー) として使用して、べき等性キー (実行名パラメータ) を使用して耐久性関数を呼び出します。

実行名

耐久関数を呼び出すときに実行名を指定できます。実行名はべき等性キーとして機能し、重複した実行を作成せずに呼び出しリクエストを安全に再試行できます。名前を指定しない場合、Lambda は一意の実行 ID を自動的に生成します。

この名前は、ユーザーのアカウント内とリージョン内で一意でなければなりません。すでに存在する実行名で関数を呼び出す場合、Lambda の動作は既存の実行の状態とペイロードが一致するかどうかによって異なります。

べき等性の動作

次の表は、実行名を指定したかどうか、既存の実行状態、ペイロードが一致するかどうかに基づいて、Lambda が呼び出しリクエストを処理する方法を示しています。

シナリオ 名前が指定されていますか? 既存の実行状態 ペイロードは同一ですか? 行動
1 不可 該当なし 該当なし 新しい実行が開始される: Lambda は一意の実行 ID を生成し、新しい実行を開始する
2 はい 存在したことがない、または保持の有効期限が切れている 該当なし 新しい実行が開始される: Lambda は指定された名前で新しい実行を開始する
3 はい 実行中 はい 冪等性の開始: Lambda は、重複を開始せずに既存の実行情報を返します。同期呼び出しの場合、これは実行中の実行への再アタッチとして動作します。
4 はい 実行中 不可 エラー: この名前の実行はすでに異なるペイロードで実行されているため、Lambda は DurableExecutionAlreadyExists エラーを返す
5 はい クローズ済み (成功、失敗、停止、またはタイムアウト) はい べき等性の開始: Lambda は、新しい実行を開始せずに既存の実行情報を返します。クローズされた実行結果が返されます
6 はい クローズ済み (成功、失敗、停止、またはタイムアウト) 不可 エラー: この名前の実行は別のペイロードですでに完了しているため、Lambda は DurableExecutionAlreadyExists エラーを返します
注記

シナリオ 3 と 5 は、重複を作成するのではなく、既存の実行情報を返すことで、Lambda が重複した呼び出しリクエストを安全に処理する、べき等性の動作を示しています。

ステップのべき等性

ステップには、デフォルトで at-least-once 実行セマンティクスがあります。待機、コールバック、または失敗後に関数が再生されると、SDK はチェックポイントログに対して各ステップをチェックします。すでに完了したステップの場合、SDK はステップロジックを再実行せずにチェックポイントされた結果を返します。ただし、ステップが失敗した場合、またはステップが完了する前に関数が中断された場合、ステップは複数回実行される可能性があります。

ステップでラップされたビジネスロジックは、発生する可能性のある再試行を処理するように、べき等性である必要があります。べき等性キーを使用して、ステップが再試行された場合でも、支払いやデータベース書き込みなどのオペレーションが 1 回だけ実行されるようにします。

例: ステップでのべき等性キーの使用

TypeScript
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js'; import { randomUUID } from 'crypto'; export const handler = withDurableExecution( async (event: any, context: DurableContext) => { // Generate idempotency key once const idempotencyKey = await context.step('generate-key', async () => { return randomUUID(); }); // Use idempotency key in payment API to prevent duplicate charges const payment = await context.step('process-payment', async () => { return paymentAPI.charge({ amount: event.amount, idempotencyKey: idempotencyKey }); }); return { statusCode: 200, payment }; } );
Python
from aws_durable_execution_sdk_python import durable_execution, DurableContext import uuid @durable_execution def handler(event, context: DurableContext): # Generate idempotency key once idempotency_key = context.step( lambda _: str(uuid.uuid4()), name='generate-key' ) # Use idempotency key in payment API to prevent duplicate charges payment = context.step( lambda _: payment_api.charge( amount=event['amount'], idempotency_key=idempotency_key ), name='process-payment' ) return {'statusCode': 200, 'payment': payment}

実行モードを AT_MOST_ONCE_PER_RETRY に設定することで、at-most-once の実行セマンティクスを使用するようにステップを設定できます。これにより、ステップは再試行ごとに最大 1 回実行されますが、ステップが完了する前に関数が中断された場合はまったく実行されない可能性があります。

SDK は、リプレイ時にステップ名と実行順序がチェックポイントログと一致していることを検証することで、決定的なリプレイを実行します。コードが別の順序または名前でステップを実行しようとすると、SDK は NonDeterministicExecutionError をスローします。

完了したステップでのリプレイの仕組み:

  1. 最初の呼び出し: 関数はステップ A を実行し、チェックポイントを作成してから待機する

  2. 2 回目の呼び出し (待機後): 関数は最初から再生されますが、ステップ A はチェックポイントされた結果をすぐに返すため、再実行されず、そのままステップ B に進みます。

  3. 3 回目の呼び出し (別の待機後): 関数は最初から再生されますが、ステップ A とステップ B はチェックポイントされた結果をすぐに返すため、そのままステップ C に進みます。

このリプレイメカニズムにより、完了したステップが再実行されることはありませんが、ビジネスロジックは完了前に再試行を処理するべき等性である必要があります。