ひとつのDynamoDB Streamsで複数のLambdaを動作させてみる

ひとつのDynamoDB Streamsで複数のLambdaを動作させてみる

できました。
Clock Icon2025.02.28

ひとつのDynamoDB Streamsで複数のLambdaを動作できたっけ?と気になったので試してみました。

おすすめの方

  • DynamoDB Streamsで動作するLambdaを設定したい方
  • ひとつのDynamoDB Streamsで複数のLambdaを動作させたい方

DynamoDB StreamsとLambdaをデプロイする

sam init

sam init \
    --runtime python3.11 \
    --name dynamodb-streams-two-lambda-sample \
    --app-template hello-world \
    --no-tracing \
    --no-application-insights \
    --structured-logging \
    --package-type Zip

AWS SAMテンプレート

2つのLambdaを作成します。

  • Lambda1
    • すべてのItemを扱う
  • Lambda2
    • InsertのItemを扱う
    • ModifyかつNewImageにmemoが存在するItemを扱う
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: dynamodb-streams-two-lambda-sample

Resources:
  # DynamoDBテーブル
  SampleTodoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: sample-todo-table
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: todoId
          AttributeType: S
      KeySchema:
        - AttributeName: todoId
          KeyType: HASH
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES

  # Lambda(その1)
  HelloWorld1Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.11
      Architectures:
      - x86_64
      Events:
        SampleTodoTableStream:
          Type: DynamoDB
          Properties:
            BatchSize: 100
            BisectBatchOnFunctionError: true
            MaximumRetryAttempts: 3
            StartingPosition: TRIM_HORIZON
            Stream: !GetAtt SampleTodoTable.StreamArn

  HelloWorld1FunctionLogGroup:
        Type: AWS::Logs::LogGroup
        Properties:
          LogGroupName: !Sub /aws/lambda/${HelloWorld1Function}

  # Lambda(その2)
  HelloWorld2Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.11
      Architectures:
      - x86_64
      Events:
        SampleTodoTableStream:
          Type: DynamoDB
          Properties:
            BatchSize: 100
            BisectBatchOnFunctionError: true
            FilterCriteria:
              Filters:
                - Pattern: '{"eventName":["INSERT"]}'
                - Pattern: '{"eventName":["MODIFY"],"dynamodb":{"NewImage":{"memo":{"S":[{"exists":true}]}}}}'
            MaximumRetryAttempts: 3
            StartingPosition: TRIM_HORIZON
            Stream: !GetAtt SampleTodoTable.StreamArn

  HelloWorld2FunctionLogGroup:
        Type: AWS::Logs::LogGroup
        Properties:
          LogGroupName: !Sub /aws/lambda/${HelloWorld2Function}

Lambdaコード

2つとも同じコードを利用します。ログ出力するだけです。

def lambda_handler(event, context):
    for record in event["Records"]:
        print(f"{record['eventName']} - {record['dynamodb'].get('NewImage')}")

デプロイ

sam deploy

動作を確認する

DynamoDBにデータを追加する

次のデータを追加します。memoは存在しません。

aws dynamodb put-item \
  --table-name sample-todo-table \
  --item '{"todoId": {"S": "todo1"}, "title": {"S": "hello"}}'

Lambda1 が動作した

01_lambda1

Lambda2 が動作した

02_lambda2

DynamoDBのデータを更新する(memoなし)

titleだけを変更します。memoはありません。

aws dynamodb update-item \
  --table-name sample-todo-table \
  --key '{"todoId": {"S": "todo1"}}' \
  --update-expression 'SET #title=:title' \
  --expression-attribute-names '{"#title": "title"}' \
  --expression-attribute-values '{":title": {"S": "world"}}'

Lambda1 が動作した

11_lambda1

Lambda2 は動作しない

02_lambda2

DynamoDBのデータを更新する(memoあり)

memoを追加します。

aws dynamodb update-item \
  --table-name sample-todo-table \
  --key '{"todoId": {"S": "todo1"}}' \
  --update-expression 'SET #memo=:memo' \
  --expression-attribute-names '{"#memo": "memo"}' \
  --expression-attribute-values '{":memo": {"S": "this is memo!"}}'

Lambda1 が動作した

31_lambda1

Lambda2 が動作した

32_lambda2

DynamoDBのデータを削除する

aws dynamodb delete-item \
  --table-name sample-todo-table \
  --key '{"todoId": {"S": "todo1"}}'

Lambda1 が動作した

41_lambda1

Lambda2 は動作しない

32_lambda2

さいごに

ひとつのDynamoDB Streamsで複数のLambdaを動作させてみました。参考になれば幸いです。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.