AWS Step FunctionsによるDynamoDBテーブルからのデータ取得時のLastEvaluatedKey対応をしてみた

2022.05.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、AWS Step FunctionsによるDynamoDBテーブルからのデータ取得時のLastEvaluatedKey対応をしてみました。

なぜLastEvaluatedKey対応をするのか

Step Functions State Machineがサポートしているペイロードサイズには256KBの上限があります。

しかしState MachineからDynamoDBテーブルへScanQueryを行う際には、取得されるアイテムセットの最大サイズは1MBとなり256KBを超えるため、Limitパラメータを使用してアイテムを取得し過ぎないようにする必要があります。

そこでLimitパラメータを使用した際にも全てのデータを取得できるように、LastEvaluatedKeyの使用に対応したStep Functions State Machineを作ってみました。

やってみた

作成したのは次のような定義のStep Functions State Machineです。

{
  "StartAt": "FirstScan",
  "States": {
    "FirstScan": {
      "Type": "Task",
      "Parameters": {
        "TableName": "hoge",
        "Limit": 1
      },
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:scan",
      "Next": "Choice"
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.LastEvaluatedKey",
          "IsPresent": true,
          "Next": "LoopedScan"
        }
      ],
      "Default": "Success"
    },
    "LoopedScan": {
      "Type": "Task",
      "Next": "Choice",
      "Parameters": {
        "TableName": "hoge",
        "Limit": 1,
        "ExclusiveStartKey": {
          "id": {
            "S.$": "$.LastEvaluatedKey.id.S"
          }
        }
      },
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:scan"
    },
    "Success": {
      "Type": "Succeed"
    }
  }
}

ワークフロー図は次のようになります。

  • DynamoDBのScan操作によりテーブルからデータ取得を行うState Machineです。
  • 1回目のFirstScanではExclusiveStartKeyを使わずにScanを行っています。
  • その後に続くLoopedScanではExclusiveStartKeyを使ってScanを行っています。
  • Scanの結果にLastEvaluatedKeyが含まれている間、ChoiceLoopedScanの間でループを行います。
  • 動作確認のためScan時のLimit1としています。実際には適当な数を指定してください。
  • 今回は省いていますが、実際にはFirstScanChoiceの間、およびLoopedScanChoiceの間に取得データを使用した何らかの処理を行うステップが入ることになるかと思います。

動作確認

データ取得対象のDynamoDBテーブルを作成し、データを投入しておきます。

State Machineを実行すると、2回目以降のScanでChoiceとLoopedScanの間でループが行われます。

実行がSuccessしました。

実行のイベント履歴を見てみます。

FirstScanで1回目のScanが行われています。

そして2回目および3回目のScanが行われた後、最後の4回目のScanではデータが無いため、その後のChoiceSuccessに進んで実行がSuccessしています。

おわりに

AWS Step FunctionsによるDynamoDBテーブルからのデータ取得時のLastEvaluatedKey対応をしてみました。

AWS Step Functionsの良いところは、なんと言ってもコードを記述せずにAWSサービスのAPIへリクエストを出来るところです。これでまた一歩、すべてのLambda FunctionをState Machineに置き換えるという野望に近づきました。

参考

以上