Amazon Web Services ブログ

新機能 – シングルリージョン限定の Amazon DynamoDB テーブルをグローバルテーブルに変換する

何十万人もの AWS のお客様が Amazon DynamoDB を活用しています。AWS は 2017 年に、DynamoDB グローバルテーブル提供開始しました。これは、マルチリージョン、マルチマスター対応の DynamoDB テーブルを独自のレプリケーションソリューションを構築して維持する必要なくデプロイできるフルマネージド型ソリューションです。グローバルテーブルを作成するときには、テーブルを使用できるようにしたい複数の AWS リージョンを指定します。DynamoDB は、これらのリージョンに同一のテーブルを作成して、進行中のデータ変更をそれらすべてに伝播するために必要なタスクのすべてを実行します。

AWS のお客様が DynamoDB グローバルテーブルを利用する主な 2 つの理由があります。クライアントに低レイテンシーの提供と、バックアップや災害対策の円滑化です。レイテンシーとは、ネットワークに転送要求を出してから実際にデータが送られてくるまでに生じる通信の遅延時間を指します。低いレイテンシーのアプリケーションでは、高い顧客エンゲージメントと、売上拡大が見込まれます。バックエンドをユーザーに近い複数のリージョンにデプロイすると、お客様のアプリケーションのレイテンシーが下がります。別のリージョンにデータをフルコピーしておくと、きわめてまれに起こるリージョン全体の不具合の際でもトラフィックをそのリージョンに切り替えやすくなります。AWS の CTO であるWerner Vogels 博士は以前に「障害は起こるものだ。あらゆるものは時間が経てば必ず障害が生じる」と述べています。

本日より、お持ちの DynamoDB テーブルはわずか数回のクリックでグローバルテーブルに変換できるようになりました。これには、直接AWS マネジメントコンソールから操作するか、または AWS コマンドラインインターフェイス (CLI)Amazon DynamoDB API のいずれかを使用します。これまでグローバルテーブルに変換できるのは空のテーブルだけでした。つまり、テーブルを作成する時点で、リージョン内のテーブルの使用法を推測する必要がありました。それが今回、テーブルのグローバル化や、既存のグローバルテーブルを別のリージョンへの拡張がいつでもできるようになりました。

レプリケーションの設定中であっても、ユーザーのアプリケーションではテーブルの使用を継続できます。テーブルにリージョンを追加すると、DynamoDB では既存のテーブルのスナップショットを使用して新しいレプリカの追加を開始します。DynamoDB で新しいレプリカを構築すると同時に、アプリケーションでは既存のリージョンに対して書き込みを継続します。進行中に生じたアップデートは最終的にはすべて新しいレプリカにレプリケーションされます。

AWS コマンドラインインターフェイス (CLI) を使用して DynamoDB グローバルテーブルを作成するために、まず米国西部 (オレゴン) リージョン (us-west-2) のローカルテーブルを作成します。

aws dynamodb create-table --region us-west-2 \
                          --table-name demo-global-table \
                          --key-schema AttributeName=id,KeyType=HASH \
                          --attribute-definitions AttributeName=id,AttributeType=S \
                          --billing-mode PAY_PER_REQUEST

次のコマンドが返されます。

{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "S"
            }
        ],
        "TableName": "demo-global-table",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "CREATING",
        "CreationDateTime": 1570278914.419,
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:us-west-2:400000000003:table/demo-global-table",
        "TableId": "0a04bd34-bbff-42dd-ae18-78d05ce641fd",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST"
        }
    }
}

テーブルを作成したら、項目をいくつか挿入します。

aws dynamodb batch-write-item --region us-west-2 --request-items file://./batch-write-items.json

(json ファイルは gist として使用できます)

次に、このテーブルをアップデートして、別リージョンとして米国東部 (バージニア北部) リージョン (us-east-1) を追加します。

aws dynamodb update-table --region us-west-2 --table-name demo-global-table --add-region us-east-1 (TBD??)

コマンドが長い JSON を返しますが、注意を要する属性は以下のとおりです。

{
...
        "TableStatus": "UPDATING",
        "TableSizeBytes": 124,
        "ItemCount": 3,
        "StreamSpecification": {
            "StreamEnabled": true,
            "StreamViewType": "NEW_AND_OLD_IMAGES"
        },
        "LatestStreamLabel": "2019-10-22T19:33:37.819",
        "LatestStreamArn": "arn:aws:dynamodb:us-west-2:400000000003:table/demo-global-table/stream/2019-10-22T19:33:37.819"
    }
...
}

AWS マネジメントコンソールに同じアップデートを行うことができます。アップデートするテーブルを選択して、[Global Tables] をクリックします。

ストリーミングを有効にしておくことは、グローバルテーブルでは必須です。まず、[Enable stream]、次に [Add region] をクリックします。

レプリケーション先のリージョン、ここでは 欧州西部 (アイルランド) を選択して、[Create replica] をクリックします。

DynamoDB では新しいリージョンへのテーブルのレプリケーションは非同期的となります。レプリケーションの進行状況は、AWS マネジメントコンソールでモニタリングできます。テーブルのステータスは、最終的に [Creating] から [Active] に変わります。このステータスはまた、DescribeTable API を呼び出して、TableStatus = Active を検証することでも確認できます。

しばらくして、新しいリージョンでテーブルをクエリできます。

aws dynamodb get-item --region eu-east-1 --table-name demo-global-table --key '{"id" : {"S" : "0123456789"}}'

{
    "Item": {
        "firstname": {
            "S": "Jeff"
        },
        "id": {
            "S": "0123456789"
        },
        "lastname": {
            "S": "Barr"
        }
    }
}

本日より、既存のローカルテーブルはグローバルテーブルにアップデートできるようになりました。 近日中に、この新機能を使用して既存のグローバルテーブルをアップデートできるツールをリリースする予定です。アップデート自体はわずか数分で終わります。ユーザーのテーブルは、アップデート中でもアプリケーションで利用可能です。

その他の改善点
データ同期に使用する内部メカニズムにも簡略化を進めています。これまでは、DynamoDB グローバルテーブルでは DynamoDB Streams を活用し、スキーマに 3 種類の属性 (aws:rep:*) を追加してデータを同期させていました。DynamoDB はレプリケーションをネイティブに管理するようになりました。同期属性をユーザーのデータにさらすことも、書き込みキャパシティーを余分に使うこともありません。

  • グローバルテーブルの各リージョンでは書き込みオペレーションが 1 回だけ生じるため、レプリケーションで使用するためにテーブルで必要な書き込みキャパシティーが削減されます。
  • この結果、2 つ目の DynamoDB Streams レコードはパブリッシュされません。
  • これまで入力していた 3 種類の aws:rep:* 属性を項目レコードに挿入されなくなります。

この変更で、ユーザーのアプリケーションに 2 つの影響があります。まず、グローバルテーブル使用の際の DynamoDB のコストが下がります。これは、同期させるために書き込みキャパシティーを追加する必要がないからです。次に、ユーザーのアプリケーションが 3 種類のテクニカルな項目 (aws:rep:*) に依存している場合、アプリケーションではわずかなコード変更が生じます。特に、DynamoDB Mapper クラスでは、aws:rep:* 属性は項目レコードに存在してはなりません。

今回の変更で、UpdateTable API もアップデートします。グローバルテーブル上のグローバルセカンダリインデックス (GSI) を修正するあらゆるオペレーション、請求モードサーバーサイドの暗号化書き込みキャパシティー単位は、ほかのすべてのレプリカにも非同期的に適用されます。

利用状況
機能が向上した Amazon DynamoDB グローバルテーブルは本日より、Amazon DynamoDB グローバルテーブルが利用できる 13 リージョンでご利用になれます。今後は、リージョンの追加も予定されています。本日の時点で、利用可能な AWS リージョンは、us-east-1 (バージニア北部)、us-west-2 (オレゴン), us-east-2 (オハイオ)、us-west-1 (北カリフォルニア)、ap-northeast-2 (ソウル)、ap-southeast-1 (シンガポール)、ap-southeast-2 (シドニー)、ap-northeast-1 (東京)、eu-central-1 (フランクフルト)、eu-west-1 (アイルランド)、eu-west-2 (ロンドン)、GovCloud (米国東部)、GovCloud (米国西部) です。

料金に変更はありません。ご請求は、追加リージョンのリソース使用分とリージョン間のデータ転送のみが対象です。

今回のアップデートはお客様からご意見の多かった要望にお応えするものです。今後もプラットフォームを提供し、追加機能を構築していく所存です。グローバルテーブルを利用用途やお使いのアプリケーションで重視する点などありましたら、今後もこちらからお送りください。

— seb