DynamoDBとPythonでユニークな連番を採番する
例えばOracleではシーケンスオブジェクト、MySQLならAuto Incrementで実装されています。
絶対に重複することがないことが保証された連番は一意なIDを振ったりするのに便利なのでシステム設計で重宝します。
NoSQLデータベースのDynamoDBではアトミックカウンタという機能を使うと連番を採番できます。
Pythonスクリプトでほんとに一意な連番が採番できるか試してみました。
ソースコード
import boto3
import time
import asyncio
dynamodb = boto3.resource('dynamodb')
table_name = 'sequence'
# テーブル作成
try:
res = dynamodb.create_table(
AttributeDefinitions = [
{
'AttributeName': 'sequence_key',
'AttributeType': 'S'
},
],
TableName = table_name,
KeySchema = [
{
'AttributeName': 'sequence_key',
'KeyType': 'HASH'
},
],
ProvisionedThroughput = {
'ReadCapacityUnits': 3,
'WriteCapacityUnits': 3
}
)
# テーブルができるまでスリープ
time.sleep(10)
except Exception as e:
pass
table = dynamodb.Table(table_name)
# sequenceをカウントアップする関数
async def countup(task_name, wait, sequence_key):
for i in range(5):
res = table.update_item(
Key= {
'sequence_key': sequence_key
},
UpdateExpression="ADD #name :increment",
ExpressionAttributeNames={
'#name':'sequence'
},
ExpressionAttributeValues={
":increment": int(1)
},
ReturnValues="UPDATED_NEW"
)
print('Task:' + task_name + ',sequence_key:' + sequence_key + ',sequence:' + str(res['Attributes']['sequence']))
await asyncio.sleep(wait)
# カウントアップ処理を並列実行
loop = asyncio.get_event_loop()
result = loop.run_until_complete(asyncio.gather(
countup("A", 0.5, 'Key1'),
countup("B", 0.5, 'Key2'),
countup("C", 1, 'Key1'),
countup("D", 1, 'Key2'),
countup("E", 1.5, 'Key1'),
countup("F", 1.5, 'Key2'),
))
実行結果
>python atomic_counter_tester.py
Task:A,sequence_key:Key1,sequence:1
Task:B,sequence_key:Key2,sequence:1
Task:C,sequence_key:Key1,sequence:2
Task:D,sequence_key:Key2,sequence:2
Task:E,sequence_key:Key1,sequence:3
Task:F,sequence_key:Key2,sequence:3
Task:A,sequence_key:Key1,sequence:4
Task:B,sequence_key:Key2,sequence:4
Task:A,sequence_key:Key1,sequence:5
Task:B,sequence_key:Key2,sequence:5
Task:C,sequence_key:Key1,sequence:6
Task:D,sequence_key:Key2,sequence:6
Task:A,sequence_key:Key1,sequence:7
Task:B,sequence_key:Key2,sequence:7
Task:E,sequence_key:Key1,sequence:8
Task:F,sequence_key:Key2,sequence:8
Task:A,sequence_key:Key1,sequence:9
Task:C,sequence_key:Key1,sequence:10
Task:B,sequence_key:Key2,sequence:9
Task:D,sequence_key:Key2,sequence:10
Task:E,sequence_key:Key1,sequence:11
Task:C,sequence_key:Key1,sequence:12
Task:F,sequence_key:Key2,sequence:11
Task:D,sequence_key:Key2,sequence:12
Task:C,sequence_key:Key1,sequence:13
Task:D,sequence_key:Key2,sequence:13
Task:E,sequence_key:Key1,sequence:14
Task:F,sequence_key:Key2,sequence:14
Task:E,sequence_key:Key1,sequence:15
Task:F,sequence_key:Key2,sequence:15
ちゃんと重複なく連番が採番されることが確認できました。
ディスカッション
コメント一覧
まだ、コメントがありません