Time to Live (TTL) の計算 - Amazon DynamoDB

Time to Live (TTL) の計算

TTL を実装する一般的な方法は、作成日または最終更新日に基づいて項目の有効期限を設定することです。これは、createdAt タイムスタンプと updatedAt タイムスタンプに時間を追加することで実現できます。例えば、新しく作成されたアイテムの TTL を createdAt + 90 日に設定できます。項目が更新されると、TTL は updatedAt + 90 日に再計算されます。

計算された有効期限は、秒単位のエポック形式である必要があります。TTL が 5 年を超えて経過すると、有効期限と削除の対象外になります。他の形式を使用すると、TTL プロセスはその項目を無視します。項目の有効期限を未来の時点に設定した場合、その期間が過ぎると項目は期限切れになります。例えば、有効期限を 1724241326 (2024 年 8 月 21 日 (月) 11:55:26 (GMT)) に設定したとします。指定した時刻以降、項目は有効期限切れになります。

項目を作成して Time to Live を設定する

次の例は、新しい項目の作成時に有効期限を計算する方法を示しています。JavaScript では TTL 属性名として 'expireAt' を使用し、Python では 'expirationDate' を使用しています。代入ステートメントは、現在の時刻を変数として取得します。この例では、有効期限は現在の時刻から 90 日後として計算されます。その後、時刻はエポック形式に変換され、TTL 属性に整数データ型として保存されます。

Python
import boto3 from datetime import datetime, timedelta def create_dynamodb_item(table_name, region, primary_key, sort_key): """ Creates a DynamoDB item with an attached expiry attribute. :param table_name: Table name for the boto3 resource to target when creating an item :param region: string representing the AWS region. Example: `us-east-1` :param primary_key: one attribute known as the partition key. :param sort_key: Also known as a range attribute. :return: Void (nothing) """ try: dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table(table_name) # Get the current time in epoch second format current_time = int(datetime.now().timestamp()) # Calculate the expiration time (90 days from now) in epoch second format expiration_time = int((datetime.now() + timedelta(days=90)).timestamp()) item = { 'primaryKey': primary_key, 'sortKey': sort_key, 'creationDate': current_time, 'expirationDate': expiration_time } table.put_item(Item=item) print("Item created successfully.") except Exception as e: print(f"Error creating item: {e}") raise # Use your own values create_dynamodb_item('your-table-name', 'us-west-2', 'your-partition-key-value', 'your-sort-key-value')
JavaScript

このリクエストでは、新しく作成されたアイテムの有効期限を計算するロジックを追加します。

import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb"; function createDynamoDBItem(table_name, region, partition_key, sort_key) { const client = new DynamoDBClient({ region: region, endpoint: `https://dynamodb.${region}.amazonaws.com` }); // Get the current time in epoch second format const current_time = Math.floor(new Date().getTime() / 1000); // Calculate the expireAt time (90 days from now) in epoch second format const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000); // Create DynamoDB item const item = { 'partitionKey': {'S': partition_key}, 'sortKey': {'S': sort_key}, 'createdAt': {'N': current_time.toString()}, 'expireAt': {'N': expire_at.toString()} }; const putItemCommand = new PutItemCommand({ TableName: table_name, Item: item, ProvisionedThroughput: { ReadCapacityUnits: 1, WriteCapacityUnits: 1, }, }); client.send(putItemCommand, function(err, data) { if (err) { console.log("Exception encountered when creating item %s, here's what happened: ", data, ex); throw err; } else { console.log("Item created successfully: %s.", data); return data; } }); } // use your own values createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');

項目を更新して Time to Live を再計算する

この例は、前のセクションの例の続きです。項目が更新された場合、有効期限を再計算できます。次の例では、expireAt タイムスタンプを現在の時刻から 90 日後として再計算します。

Python
import boto3 from datetime import datetime, timedelta def update_dynamodb_item(table_name, region, primary_key, sort_key): """ Update an existing DynamoDB item with a TTL. :param table_name: Name of the DynamoDB table :param region: AWS Region of the table - example `us-east-1` :param primary_key: one attribute known as the partition key. :param sort_key: Also known as a range attribute. :return: Void (nothing) """ try: # Create the DynamoDB resource. dynamodb = boto3.resource('dynamodb', region_name=region) table = dynamodb.Table(table_name) # Get the current time in epoch second format current_time = int(datetime.now().timestamp()) # Calculate the expireAt time (90 days from now) in epoch second format expire_at = int((datetime.now() + timedelta(days=90)).timestamp()) table.update_item( Key={ 'partitionKey': primary_key, 'sortKey': sort_key }, UpdateExpression="set updatedAt=:c, expireAt=:e", ExpressionAttributeValues={ ':c': current_time, ':e': expire_at }, ) print("Item updated successfully.") except Exception as e: print(f"Error updating item: {e}") # Replace with your own values update_dynamodb_item('your-table-name', 'us-west-2', 'your-partition-key-value', 'your-sort-key-value')

更新操作の出力から、createdAt 時刻は変更されていないが、updatedAt 時刻と expireAt 時刻が更新されていることがわかります。expireAt 時刻は、最終更新日から 90 日後である 2023 年 10 月 19 日 (木) 午後 1 時 27 分 15 秒に設定されました。

partition_key createdAt updatedAt expireAt attribute_1 attribute_2

some_value

2023-07-17 14:11:05.322323 2023-07-19 13:27:15.213423 1697722035 new_value some_value
JavaScript
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb"; import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; async function updateDynamoDBItem(tableName, region, partitionKey, sortKey) { const client = new DynamoDBClient({ region: region, endpoint: `https://dynamodb.${region}.amazonaws.com` }); const currentTime = Math.floor(Date.now() / 1000); const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000); ////is there a better way to do this? const params = { TableName: tableName, Key: marshall({ partitionKey: partitionKey, sortKey: sortKey }), UpdateExpression: "SET updatedAt = :c, expireAt = :e", ExpressionAttributeValues: marshall({ ":c": currentTime, ":e": expireAt }), }; try { const data = await client.send(new UpdateItemCommand(params)); const responseData = unmarshall(data.Attributes); console.log("Item updated successfully: %s", responseData); return responseData; } catch (err) { console.error("Error updating item:", err); throw err; } } //enter your values here updateDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');

この概要で説明した TTL の例は、最近更新された項目だけをテーブルに保持する方法を示しています。更新された項目は有効期限が延びますが、作成後に更新されなかった項目は有効期限が切れて無料で削除されるため、ストレージが削減され、テーブルが整理されます。