DynamoDB Global Table v2
-
DynamoDB グローバルテーブルにはバージョン2019.11.21とバージョン2017.11.29の2バージョンがある
- 2019.11.21が現行バージョン
- グローバルテーブルの作成手順によっては現在でも2017.11.29のほうが作成される
-
aws dynamodb create-global-table
すると2017.11.29 -
aws dynamodb update-table
から--replica-updates
オプション付けると2019.11.21
-
- 作成済みグローバルテーブルのバージョン確認方法
- コンソールの場合: DynamoDB > テーブル > テーブルを選択 > 「グローバルテーブル」タブを選択
- CLIの場合:
aws dynamodb describe-table
の出力にGlobalTableVersionが含まれる
参考
グローバルテーブルの作成(CLI)
- DynamoDBグローバルテーブルの操作はCloudFormationに対応していないっぽいのでCLIかコンソールから行う必要がある
- CLIのバージョンは一応1でも2でも行けるっぽい
バージョン2017.11.29の場合
-
aws dynamodb create-table
で各リージョンにレプリカテーブルを作成- ⭐DynamoDBストリームを有効化する必要がある
-
aws dynamodb create-global-table
でグローバルテーブルを作成-
--global-table-name
を①で作ったレプリカテーブル名と統一させる必要がある - aws dynamodb create-global-table コマンドで作成できるのはバージョン2017.11.29のみ。
-
- レプリカを追加する場合は ①
create-table
でレプリカテーブルを作成して、②update-global-tableでレプリカテーブルを追加する - レプリカを削除する場合は
update-global-table
の--replica-updates
オプションに"Delete"
とリージョン名を指定
- ❓
delete-global-table
オプションは存在しないけどupdate-global-table
でレプリカを全削除すればグローバルテーブルはなくなる?
バージョン2019.11.21の場合
-
aws dynamodb create-table
でレプリカテーブルを作成- ⭐DynamoDBストリームを有効化する必要がある
-
aws dynamodb update-tableの
--replica-updates
オプションでリージョンを指定し、レプリカの作成/更新/削除を行える- バージョン2017.11.29とは異なり明示的にグローバルテーブルを作成するわけではない
- シングルリージョンのテーブルをいつでもグローバルテーブルに変更できるようになったので、「グローバルテーブルを作る」という概念がなくなった?
バージョン2019.11.21 のデプロイ
CDK
replicationRegions
属性を指定して作成できる
import * as dynamodb from '@aws-cdk/aws-dynamodb';
const globalTable = new dynamodb.Table(this, 'Table', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'],
});
CloudFormation
レプリカ/グローバルテーブルに関する構文は存在しない。
- メインとなるテーブルだけテンプレートで作成してCLIからレプリカ作成?
- レプリカ含めてテンプレートで作成して後からグローバルテーブルとして指定できる?
- ❌ できない。同名の単一テーブルが既に存在する場合に、あとから
update-table --replica-updates
でそのリージョンを指定するとエラーになる。
- ❌ できない。同名の単一テーブルが既に存在する場合に、あとから
- カスタムリソースを使ってテンプレートデプロイ後にCLIコマンドたたく?
CDKでやってみる
aws-cdk: 1.74.0 (build e86602f)
from aws_cdk import (
core,
aws_dynamodb as _ddb
)
class DynamoGlobalTableStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = _ddb.Table(self,
id='global-table-sample',
partition_key=_ddb.Attribute(name='id', type=_ddb.AttributeType.STRING),
replication_regions=['ap-northeast-1', 'eu-central-1', 'us-west-2']
)
cdk synth
でテンプレートを出力したところ globaltablesample
(+末尾にランダムな文字列)というAWS::DynamoDB::Tableリソースと、Custom::DynamoDBReplica
というカスタムリソースで3リージョン分のレプリカテーブルリソースが定義されていた
AWS::CloudFormation::CustomResource
CDKのバージョン2019.11.21対応プルリク。synthの中身だけ見てもわかんない感じかな???
グローバルテーブルのバージョン 2019.11.21 (現行) への更新
更新の前に・・・
バージョン2019.11.21では以下の要件を満たしている必要がある。
- 各リージョンのレプリカテーブル間で、
- GSIが一致
- 暗号化設定が一致
- TTL設定が一致
- すべてのレプリカテーブルの書き込みCUに対して、AutoScalingまたはOndemandCapacityが有効になっている
必要なアクセス権限
バージョン 2019.11.21 (現行) に更新するには、レプリカリージョン間の dynamodb:UpdateGlobalTableVersion アクセス許可が必要です。これらのアクセス許可は、DynamoDB コンソールへのアクセスとテーブルの表示に必要なアクセス許可に追加して必要です。
更新プロセス
- 更新プロセス中はグローバルテーブルの状態がACTIVE→UPDATINGに変わる
- 数分から1時間以内には完了する
- 更新プロセス中、読み取りトラフィックと書き込みトラフィックに対して引き続き使用可能
- ただしAutoScalingによるCU変更が行われないので、オンデマンド容量に変えることを推奨。
- 更新プロセスが完了すると、テーブルのステータスはACTIVEに戻る。
- テーブルの状態は
DescribeTable
を使用/Dynamoコンソールの「テーブル」ビューから確認。
❓
update-table --replica-updates
でeu-central-1にレプリカを作成、その後eu-central-1を指定してupdate-table --replica-updates
でus-west-1を追加 はできる?
❓ ap-northeast-1にテーブルを作成、✔ できる。レプリカの追加を支持するテーブルはどのリージョンのレプリカでもよい
create-global-table
すると?
❓ 2019.11.21のグローバルテーブルに対して✔ エラーになる
$ aws dynamodb create-global-table \
--global-table-name Music \
--replication-group RegionName=ap-northeast-1 RegionName=eu-central-1 RegionName=us-west-2 \
--region ap-northeast-1
An error occurred (GlobalTableAlreadyExistsException) when calling the CreateGlobalTable operation: Global table already exists: Global table with name: 'Music' already exists.
❓ [2019.11.21] ap-northeast-1にテーブルを作成したのち、eu-central-1&us-west-2にレプリカを作成した後、ap-northeast-1のテーブルを削除するとどうなる?
✔ 「レプリカは、過去24時間にテーブルに追加された新しいレプリカのソース領域として機能したため、削除できません。」
24時間たてばいける?
$ aws dynamodb update-table --table-name Music --region eu-central-1 --cli-input-json \
'{
"ReplicaUpdates":
[
{
"Delete": {
"RegionName": "ap-northeast-1"
}
}
]
}'
An error occurred (ValidationException) when calling the UpdateTable operation: Replica cannot be deleted because it has acted as a source region for new replica(s) being added to the table in the last 24 hours.
update-table
でレプリカ削除を指定しないといけないのか、delete-table
でもいいのか
❓ ✔ delete-tableでも行ける
❓ create-tableでも後からレプリカ追加できるのか
✔ グローバルテーブルには追加されない。同一名の単一テーブルとして作成される。
❓ さらにこの後、作成したテーブルをレプリカとして登録できるか?
✔ エラーになる。
# 普通のMusicテーブルがus-west-2に作成済みの場合
$ aws dynamodb update-table --table-name Music --region ap-northeast-1 --cli-input-json '{
"ReplicaUpdates":
[
{
"Create": {
"RegionName": "us-west-2"
}
}
]
}'
An error occurred (ValidationException) when calling the UpdateTable operation: Failed to create a the new replica of table with name: ‘Music’ because one or more replicas already existed as tables.
update-table --replica-updates
するとどうなる?
❓ 2017.11.29のグローバルテーブルに対してバージョン2019.11.21になって変わったこと
- 自動的に作成されていた属性がなくなった
- バージョン 2017.11.29ではレプリケーションの実行と競合可決の管理のために、書き込まれたItemに対して以下の3つの属性が書き込まれていた
- aws:rep:deleting
- aws:rep:updatetime
- aws:rep:updateregion
- バージョン2019.11.21ではユーザーに見えないところで管理されるようになったので、これらの属性が作成・更新されなくなる
- DynamoDBマッパーがこれらの属性を使用しなくなる
- バージョン 2017.11.29ではレプリケーションの実行と競合可決の管理のために、書き込まれたItemに対して以下の3つの属性が書き込まれていた
- DynamoDB ストリーム は、書き込みごとに (2 つではなく) 1 つのレコードのみをパブリッシュする
- ❓前は2レコードだった?
- バージョン 2017.11.29からバージョン2019.11.21へ更新した場合、
ReplicationLatency
メトリクスが増加する場合がある。 これはバージョン間のReplicationLatency
メトリクスの違いによるもの。- [2017.11.29] Itemの更新が1つのレプリカのDynamoDBストリームに現れてから、別のリージョンのレプリカテーブルに現れるまでにかかる時間
- [2019.11.21] Itemが1つのテーブルに書き込まれてから、別のリージョンのレプリカテーブルに現れるまでにかかる時間
- なお、両バージョン共に「ミリ秒で表し、送信元リージョンと送信先リージョンのペアに対して出力されます」という点はおなじ。これは
ReplicationLetency
メトリクスにReceivingRegion
というディメンションが付与されており、ReceivingRegion
に送信先リージョンが指定されている。(ディメンションについてはこちら) - 「送信元」のディメンションが無いのはグローバルテーブル作成時に指定したリージョンが送信元固定になってる?
- バージョン2017.11.29の場合、
create-globa-table
じの--region
で指定したリージョンが送信元?(以下の場合us-east-2)$ aws dynamodb create-global-table \ --global-table-name MusicCollection \ --replication-group RegionName=us-east-2 RegionName=us-east-1 \ --region us-east-2
- バージョン2017.11.29の場合、
- なお、両バージョン共に「ミリ秒で表し、送信元リージョンと送信先リージョンのペアに対して出力されます」という点はおなじ。これは
- バージョン2019.11.21では
PendingReplicationCount
メトリクスがなくなった?
参考
Global Tables: How It Works:Global Table Concepts
A global table is a collection of one or more replica tables, all owned by a single AWS account.
「グローバルテーブルは1つ以上のレプリカテーブルのコレクションで、すべて単一のAWSアカウント内で所有する。」これは両バージョン変わらず
A replica table (or replica, for short) is a single DynamoDB table that functions as a part of a global table. Each replica stores the same set of data items. Any given global table can only have one replica table per AWS Region.
これも一緒。レプリカテーブルの説明
続いてグローバルテーブル作成に関するセクション。ここから内容が異なる
2017.11.29には以下のように記載。
The following is a conceptual overview of how a global table is created.
- Create an ordinary DynamoDB table, with DynamoDB Streams enabled, in an AWS Region.
- Repeat step 1 for every other Region where you want to replicate your data.
- Define a DynamoDB global table based on the tables that you have created.
The AWS Management Console automates these tasks, so you can create a global table more quickly and easily. For more information, see Creating a Global Table.
- DynamoDBストリームを有効にした普通のDynamoDBテーブルをリージョンに作成
- レプリケートしたいすべてのリージョンに対して①を繰り返す
- 作成したテーブルに基づいてDynamoDBグローバルテーブルを定義する。
これらの記述は2019.11.21のほうにはない。create-global-tableする必要がなくなったためと思われる。
[2017.11.29] The resulting DynamoDB global table consists of multiple replica tables, one per Region, that DynamoDB treats as a single unit. Every replica has the same table name and the same primary key schema. When an application writes data to a replica table in one Region, DynamoDB automatically propagates the write to the other replica tables in the other AWS Regions.
[2019.11.21] When you create a DynamoDB global table, it consists of multiple replica tables (one per Region) that DynamoDB treats as a single unit. Every replica has the same table name and the same primary key schema. When an application writes data to a replica table in one Region, DynamoDB propagates the write to the other replica tables in the other AWS Regions automatically.
微妙に表現は違うが書いてあることはだいたい同じ。各リージョンのレプリカはそれぞれ単一のDynamoDBテーブルとして扱われる。また各レプリカは同一のテーブル名とプライマリキースキーマを持つ。1リージョンのレプリカテーブルにデータが書き込まれると、自動で他リージョンのレプリカにも伝搬される。
2017.11.29のみ独自の属性が書き込まれる記載がある(aws:rep:*
)。2019.11.21
ではこれらの属性は作成されなくなった。
次が重要。
[2017.11.29] You can add replica tables to the global table so that it can be available in additional Regions. (To do this, the global table must be empty. In other words, none of the replica tables can have any data in them.)
[2019.11.21] You can add replica tables to the global table so that it can be available in additional Regions.
2017.11.29のほうは、「レプリカをグローバルテーブルに追加するためには、グローバルテーブルが空である必要がある。言い換えれば、どのレプリカテーブルもデータを持っていいてはいけない。」
と記載がある。
ということは別テーブル名で新しいレプリカ含むグローバルテーブルを新規に作成したのち、旧グローバルテーブルからデータを移行しなければならない????
[2017.11.29] You can also remove a replica table from a global table. If you do this, the table is completely disassociated from the global table. This newly independent table no longer interacts with the global table, and data is no longer propagated to or from the global table.
なぜか2017.11.29のほうだけ削除に関する記載がある
ver 2017.11.29について
update-table
でbilling-modeを変えると単一のレプリカにしか反映されないので、
update-global-table-settings
で--global-table-billing-mode
を設定するとすべてのレプリカに反映される