ひとつのDynamoDB Streamsで複数のLambdaを動作させてみる
できました。
ひとつの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 が動作した
Lambda2 が動作した
memo
なし)
DynamoDBのデータを更新する(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 が動作した
Lambda2 は動作しない
memo
あり)
DynamoDBのデータを更新する(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 が動作した
Lambda2 が動作した
DynamoDBのデータを削除する
aws dynamodb delete-item \
--table-name sample-todo-table \
--key '{"todoId": {"S": "todo1"}}'
Lambda1 が動作した
Lambda2 は動作しない
さいごに
ひとつのDynamoDB Streamsで複数のLambdaを動作させてみました。参考になれば幸いです。