DynamoDBをキャッシュとして使用している。そのデータは一時的に保持するデータであり、無ければ新しく作成される。そのデータは永続的に保持していたのだが、一定時間過ぎたキャッシュを削除する状況に出会った。
通常DynamoDBのアイテムを削除する場合、DeleteItemを用いて削除するが、DynamoDBは上記の状況を考慮し、特定の属性に設定された時刻が現在時刻よりも古ければ削除する Time To Live
という機能を提供している。今回はDynamoDBのTime to Live機能を設定したテーブルに対しアイテムを登録し、実際にこの機能によってアイテムが削除されることを確認することにした。
IAMの設定
強い権限で操作をしているとオペミスにより思わぬトラブルを招くリスクがある。もうそんなのは嫌なので、新しくIAMポリシーを作成し、新しく作成したユーザー に付与し、それを用いて検証を行うことにする。
ポリシーとしては次の権限が必要になる。
内容 | 権限 |
---|---|
DynamoDBテーブルの作成 | dynamodb:CreateTable |
DynamoDBテーブルへのTTLの設定 | dynamodb:UpdateTimeToLive |
DynamoDBテーブルへのアイテムの登録 | dynamodb:PutItem |
検証用のテーブルを作成するため、CreateTableも追加することにした。ポリシーのJSONを記載する。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"dynamodb:CreateTable",
"dynamodb:UpdateTimeToLive",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:*:table/testing"
}
]
}
これを元にIAMポリシーを作成、検証用ユーザーに付与した。
DynamoDBテーブルの作成
testingという名前のテーブルを検証用に作成する。コマンド実行のためのスケルトン用JSONを編集し次のように編集する。
{
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"TableName": "testing",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"BillingMode": "PROVISIONED",
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"TableClass": "STANDARD"
}
テスト用のテーブルを作成する。
aws dynamodb create-table --cli-input-json file://dynamodb-create-table.json
DynamoDBテーブルのTime To Live機能を有効化する
作成したDynamoDBテーブルのTime To Live機能を有効化する。設定する属性はどれでもよく、今回は ttl
という属性がTime To Live機能の対象になるように設定する。
{
"TableName": "testing",
"TimeToLiveSpecification": {
"Enabled": true,
"AttributeName": "ttl"
}
}
テスト用のテーブルのTTLの機能を有効化する。
aws dynamodb update-time-to-live --cli-input-json file://dynamodb-update-time-to-live.json
DynamoDBテーブルにアイテムを登録する
アイテムが削除されることを確認するために、2つのアイテムを登録する。1つ目はttl属性を持たないアイテム、2つ目はttlを指定していて値が現在のUnixエポックタイムのものを登録する。
ttl属性なし
ttl属性をしていしないため、おそらく削除されないアイテム。idは first
とする。
{
"TableName": "testing",
"Item": {
"id": {
"S": "first"
}
}
}
アイテムを登録する。
aws dynamodb put-item --cli-input-json file://dynamodb-put-item-first.json
ttl属性あり(現在のUnixエポックタイムを設定)
ttl属性に現在のUnixエポックタイムを設定したため、おそらく削除されるアイテム。idは second
とする。
{
"TableName": "testing",
"Item": {
"id": {
"S": "second"
},
"ttl": {
"N": "1671263329"
}
}
}
アイテムを登録する。
aws dynamodb put-item --cli-input-json file://dynamodb-put-item-second.json
48時間待たないと削除されない
ここまで実行しAWSコンソール上からアイテムの削除を待っていたが、しばらく待っても削除されなかった。理由がはっきりしなかったため、ドキュメントを確認することにした。ドキュメントには「アイテムの削除は期限が切れてから48時間以内に削除される1」との記載があった。どうやら期限が切れたら即座に削除されるわけではなく、2日間の猶予期間があるようだ。その間アイテムは存在するためGetItemで取得できる。「デフォルトで48時間」との記載があるので、タイミングを変更できるのかもしれないが、AWSコンソール上にはそのようなUIはなく、またスケルトン上もそのような属性はなかった。
削除を確認する
確認のためには時が過ぎるのを待つしかないため、ただ窓の外を眺めつつ待つことにした。そうして2日が経った。再度、AWSコンソールからアイテムを確認すると、id=secondのアイテムは無くなっていた。期待通りの挙動を確認できた。
TerraformでTime To Liveを適応する
DynamoDBの管理をTerraformを用いて行うケースもあるだろう。Terrafromのaws_dynamodb_tableリソースは、Time To Liveを設定するためのttlという項目を提供している2。次のように設定することでTime To Liveの有効/無効を切り替えることができる。
resource "aws_dynamodb_table" "testing" {
name = "testing"
〜省略〜
ttl {
attribute_name = "ttl"
enabled = true
}
〜省略〜
}
まとめ
今回はAWS DynamoDBのアイテムを自動削除するTime To Live機能を確認した。アイテムは即座に削除されるのではなく、期限が切れてから48時間以内に削除される。厳密に48時間以内かどうかは確認できなかったが、2日程度待つとアイテムが削除されることを確認した。またTerraformを用いたTime To Liveの設定方法についても確認した。