Open9

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の場合

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/globaltables.tutorial.html#creategt_cli
  1. aws dynamodb create-tableで各リージョンにレプリカテーブルを作成
    • ⭐DynamoDBストリームを有効化する必要がある
  2. aws dynamodb create-global-tableでグローバルテーブルを作成
    • --global-table-nameを①で作ったレプリカテーブル名と統一させる必要がある
    • aws dynamodb create-global-table コマンドで作成できるのはバージョン2017.11.29のみ
  3. レプリカを追加する場合は ①create-tableでレプリカテーブルを作成して、②update-global-tableでレプリカテーブルを追加する
  4. レプリカを削除する場合はupdate-global-table--replica-updatesオプションに"Delete"とリージョン名を指定

  • delete-global-tableオプションは存在しないけどupdate-global-tableでレプリカを全削除すればグローバルテーブルはなくなる?

バージョン2019.11.21の場合

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/V2globaltables.tutorial.html#V2creategt_cli
  1. aws dynamodb create-tableでレプリカテーブルを作成
    • ⭐DynamoDBストリームを有効化する必要がある
  2. aws dynamodb update-table--replica-updatesオプションでリージョンを指定し、レプリカの作成/更新/削除を行える

バージョン2019.11.21 のデプロイ

CDK

https://docs.aws.amazon.com/cdk/api/latest/docs/aws-dynamodb-readme.html#amazon-dynamodb-global-tables

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

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html

レプリカ/グローバルテーブルに関する構文は存在しない。

  • メインとなるテーブルだけテンプレートで作成してCLIからレプリカ作成?
  • レプリカ含めてテンプレートで作成して後からグローバルテーブルとして指定できる?
    • ❌ できない。同名の単一テーブルが既に存在する場合に、あとからupdate-table --replica-updatesでそのリージョンを指定するとエラーになる。
  • カスタムリソースを使ってテンプレートデプロイ後にCLIコマンドたたく?

CDKでやってみる

aws-cdk: 1.74.0 (build e86602f)

stack.py
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コンソールの「テーブル」ビューから確認。

❓ ap-northeast-1にテーブルを作成、update-table --replica-updatesでeu-central-1にレプリカを作成、その後eu-central-1を指定してupdate-table --replica-updatesでus-west-1を追加 はできる?

✔ できる。レプリカの追加を支持するテーブルはどのリージョンのレプリカでもよい


❓ 2019.11.21のグローバルテーブルに対してcreate-global-tableすると?

✔ エラーになる

$ 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.

❓ 2017.11.29のグローバルテーブルに対してupdate-table --replica-updatesするとどうなる?

バージョン2019.11.21になって変わったこと

  • 自動的に作成されていた属性がなくなった
    • バージョン 2017.11.29ではレプリケーションの実行と競合可決の管理のために、書き込まれたItemに対して以下の3つの属性が書き込まれていた
      • aws:rep:deleting
      • aws:rep:updatetime
      • aws:rep:updateregion
    • バージョン2019.11.21ではユーザーに見えないところで管理されるようになったので、これらの属性が作成・更新されなくなる
    • DynamoDBマッパーがこれらの属性を使用しなくなる
  • 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
          
  • バージョン2019.11.21ではPendingReplicationCountメトリクスがなくなった?

参考

Global Tables: How It Works:Global Table Concepts

2017.11.29
2019.11.21


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.

  1. Create an ordinary DynamoDB table, with DynamoDB Streams enabled, in an AWS Region.
  2. Repeat step 1 for every other Region where you want to replicate your data.
  3. 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.
  1. DynamoDBストリームを有効にした普通のDynamoDBテーブルをリージョンに作成
  2. レプリケートしたいすべてのリージョンに対して①を繰り返す
  3. 作成したテーブルに基づいて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を設定するとすべてのレプリカに反映される

ログインするとコメントできます