kakakakakku blog

Weekly Tech Blog: Keep on Learning!

LocalStack を使って DynamoDB TTL 機能をローカル環境で試す

LocalStack は Amazon DynamoDB TTL (Time To Live) 機能をサポートしている❗️Amazon DynamoDB を実環境にデプロイする前に TTL の動作確認ができて便利👌最近 LocalStack の Amazon DynamoDB TTL 機能を試す機会があって,簡単にまとめておこうと思う〜 \( 'ω')/ LocalStack の Amazon DynamoDB で TTL 機能がサポートされていることは案外知られていなかったりすると思う.

docs.localstack.cloud

LocalStack の Amazon DynamoDB TTL 機能

LocalStack の Amazon DynamoDB TTL 機能を使うためには大きく2種類の選択肢がある📝

  1. 1時間ごとに削除する
  2. API を実行する

1. 1時間ごとに削除する

1時間ごとに削除する仕組みは Amazon DynamoDB TTL 機能の挙動に似ていて,期限切れになった後に非同期に削除される🗑実際の Amazon DynamoDB TTL 機能はドキュメントに 数日以内に削除 と書いてあって,LocalStack だと1時間ごとに削除されるという違いがある.

docs.aws.amazon.com

1時間ごとに削除する場合は環境変数 DYNAMODB_REMOVE_EXPIRED_ITEMS=1 を設定して LocalStack を起動する必要がある🚀

$ DYNAMODB_REMOVE_EXPIRED_ITEMS=1 localstack start -d

動作確認のために awslocal コマンドで Amazon DynamoDB テーブルを作る.今回は expired_at を Amazon DynamoDB TTL 機能の対象にする👌

$ awslocal dynamodb create-table \
    --table-name sandbox-ttl \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST

$ awslocal dynamodb update-time-to-live \
    --table-name sandbox-ttl \
    --time-to-live-specification 'Enabled=true, AttributeName=expired_at'

そしてサンプルデータを投入する.今回は expired_at18:00 / 19:00 / 20:00 を設定しておく.

$ awslocal dynamodb put-item --table-name sandbox-ttl \
  --item '{ "id": { "S": "076c35eb-21bb-4f48-aa38-b27e513c0774" }, "title": { "S": "Title A" }, "expired_at": { "N": "1721466000" } }'
$ awslocal dynamodb put-item --table-name sandbox-ttl \
  --item '{ "id": { "S": "16244eb7-22ff-44c3-8411-17cc270fedf9" }, "title": { "S": "Title B" }, "expired_at": { "N": "1721469600" } }'
$ awslocal dynamodb put-item --table-name sandbox-ttl \
  --item '{ "id": { "S": "654a47a1-cd1c-42e8-9eff-0e5296442cb8" }, "title": { "S": "Title C" }, "expired_at": { "N": "1721473200" } }'
id title expired_at
076c35eb-21bb-4f48-aa38-b27e513c0774 Title A 1721466000(2024/07/20 18:00:00
16244eb7-22ff-44c3-8411-17cc270fedf9 Title B 1721469600(2024/07/20 19:00:00
654a47a1-cd1c-42e8-9eff-0e5296442cb8 Title C 1721473200(2024/07/20 20:00:00

サンプルデータ投入直後の状態を確認する.

$ awslocal dynamodb scan --table-name sandbox-ttl
{
    "Items": [
        {
            "title": {
                "S": "Title A"
            },
            "id": {
                "S": "076c35eb-21bb-4f48-aa38-b27e513c0774"
            },
            "expired_at": {
                "N": "1721466000"
            }
        },
        {
            "title": {
                "S": "Title C"
            },
            "id": {
                "S": "654a47a1-cd1c-42e8-9eff-0e5296442cb8"
            },
            "expired_at": {
                "N": "1721473200"
            }
        },
        {
            "title": {
                "S": "Title B"
            },
            "id": {
                "S": "16244eb7-22ff-44c3-8411-17cc270fedf9"
            },
            "expired_at": {
                "N": "1721469600"
            }
        }
    ],
    "Count": 3,
    "ScannedCount": 3,
    "ConsumedCapacity": null
}

1時間ほど待って,もう一度データを確認する.期待通りに Title A のデータが消えている👌

$ awslocal dynamodb scan --table-name sandbox-ttl
{
    "Items": [
        {
            "title": {
                "S": "Title C"
            },
            "id": {
                "S": "654a47a1-cd1c-42e8-9eff-0e5296442cb8"
            },
            "expired_at": {
                "N": "1721473200"
            }
        },
        {
            "title": {
                "S": "Title B"
            },
            "id": {
                "S": "16244eb7-22ff-44c3-8411-17cc270fedf9"
            },
            "expired_at": {
                "N": "1721469600"
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 2,
    "ConsumedCapacity": null
}

2. API を実行する

次に API を試す.LocalStack は一時的な動作確認で使うことも多く,個人的は1時間待つよりは API でサッと消せるのが便利だと思う❗️LocalStack には /_aws/dynamodb/expired という Amazon DynamoDB TTL 機能専用の API エンドポイントがある👌

同じサンプルデータのまま API を実行する.

$ curl -X DELETE localhost:4566/_aws/dynamodb/expired
{"ExpiredItems": 1}

データを確認すると,期待通りに Title B のデータが消えている👌

$ awslocal dynamodb scan --table-name sandbox-ttl
{
    "Items": [
        {
            "title": {
                "S": "Title C"
            },
            "id": {
                "S": "654a47a1-cd1c-42e8-9eff-0e5296442cb8"
            },
            "expired_at": {
                "N": "1721473200"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "ConsumedCapacity": null
}

その他

LocalStack ドキュメントを読んでいたらエンドポイントの表記に誤りがあって修正しておいた ✅

すぐに merge してもらえた〜 \( 'ω')/

github.com