AWS Database Blog

Use Amazon DynamoDB global tables in DynamoDB Shell

Global tables build on the global Amazon DynamoDB footprint to provide you with a fully managed, multi-Region, multi-active database that delivers fast, local, read and write performance for massively scaled, global applications. Global tables replicate your DynamoDB tables automatically across your choice of AWS Regions.

DynamoDB Shell is an interactive command line interface for DynamoDB. You can perform data definition language (DDL) and data manipulation language (DML) operations through DynamoDB Shell and it now has DDL support for global table operations. For an introduction to querying data with DynamoDB Shell, refer to Query data with DynamoDB Shell – a command line interface for Amazon DynamoDB.

This post provides a brief recap of some of the features of DynamoDB Shell and introduces support for global tables. It provides a quick illustration of how new users of DynamoDB can get started with global tables.

DynamoDB global tables

Global applications benefit from having their data close to customers. With a globally distributed customer base, this means that application designers need a database that can maintain their customer data in a globally distributed and consistent manner. With DynamoDB global tables, you can create a table that operates in many Regions, is fully managed, and multi-active. Updates to data in any Region are automatically replicated to all other Regions by DynamoDB. Data is guaranteed to be eventually consistent, and should the same item be updated in multiple Regions at almost the same instant, the later update will prevail. For more details about DynamoDB global tables, see Amazon DynamoDB global tables.

There are two versions of DynamoDB global tables. DynamoDB Shell supports DDL only for the current version, 2019.11.21, which provides greater flexibility, higher efficiency, and is more frugal with write capacity than the earlier version.

DynamoDB Shell use case

To illustrate using DynamoDB Shell with global tables, consider an application that tracks airline flights. In the following example, you create a table for an application in DynamoDB Shell. Recall that in DynamoDB Shell, the prompt contains the name of the connected Region. At any point in time, a session is connected to only one Region. You can use the connect command to switch Regions. You start connected to us-east-2 (United States, Ohio):

us-east-2> create table flights ( fltno string, route string ) primary key ( fltno hash, route range );
CREATE
us-east-2>

Then you populate some data into the table:

us-east-2> insert into flights ( fltno, route, status ) values ( "QR573", "BLR-DOH", "SCHEDULED" ), ("QR743", "DOH-BOS", "SCHEDULED");
INSERT
INSERT
us-east-2> select * from flights;
{fltno: QR743, route: DOH-BOS, status: SCHEDULED}
{fltno: QR573, route: BLR-DOH, status: SCHEDULED}
us-east-2>

This table is in the us-east-2 Region. Any application that wants to access this data will have to connect to us-east-2.

Now let’s convert it into a global table with a replica in eu-west-3 (Paris (France)) and ap-south-1 (Mumbai (India)):

us-east-2> alter table flights add replica ap-south-1;
ALTER
us-east-2> alter table flights add replica eu-west-3;
ALTER
us-east-2>

If you run the following describe command right away, you can see the replicas being created:

us-east-2> describe flights;
Name: flights (ACTIVE)
Key: HASH fltno, RANGE route
[...]
Replica Region: eu-west-3 (Status: CREATING)
Replica Region: ap-south-1 (Status: CREATING)
Replica Region: us-east-2 (Status: ACTIVE)
us-east-2>

Wait for a few minutes as the DynamoDB global tables set up the table in all three locations and establish multi-active replication between the locations. If there is a lot of data in the table when you add a replica, it might take a little longer for the replica to be established. Existing replicas (in this case, us-east-2) remain available while new replicas are created and populated.

After a few minutes, you’ll see the following code:

us-east-2> describe flights;
Name: flights (ACTIVE)
Key: HASH fltno, RANGE route
[...]
Replica Region: eu-west-3 (Status: ACTIVE)
Replica Region: ap-south-1 (Status: ACTIVE)
Replica Region: us-east-2 (Status: ACTIVE)
us-east-2>

Now let’s look at the data in the ap-south-1 Region:

us-east-2> connect ap-south-1;
CONNECT
ap-south-1> select * from flights;
{fltno: QR743, route: DOH-BOS, status: SCHEDULED}
{fltno: QR573, route: BLR-DOH, status: SCHEDULED}
ap-south-1>

DynamoDB successfully replicated data from us-east-2 to ap-south-1.

Now, assume that a flight departed from BLR to DOH (Bengaluru, India, to Doha, Qatar). An application now needs to switch the status of flight QR573 to DEPARTED. That component, probably in India, would logically connect to the database in ap-south-1 and perform the update:

ap-south-1> update flights set status = "DEPARTED" where fltno = "QR573" and route = "BLR-DOH";
UPDATE (0 read, 1 modified, 0 ccf)
ap-south-1>

A family member of a passenger on this flight happens to be in Boston and wants to see what the status of the flight is, so they visit a webpage—which is running in us-east-2—and look up the status of flight QR573. The webpage looks in us-east-2:

ap-south-1> connect us-east-2;
CONNECT
us-east-2> select * from flights where fltno = "QR573";
{fltno: QR573, route: BLR-DOH, status: DEPARTED}
us-east-2>

DynamoDB global tables replicated the write from ap-south-1 to us-east-2 without any involvement from the application!

When the flight lands in DOH, an application there updates the table. The application is hosted in Europe and knows to use the local Region, eu-west-3:

eu-west-3> select * from flights where fltno = "QR573";
{fltno: QR573, route: BLR-DOH, status: DEPARTED}
eu-west-3> update flights set status = "ARRIVED" where fltno = "QR573" and route = "BLR-DOH";
UPDATE (0 read, 1 modified, 0 ccf)
eu-west-3> select * from flights where fltno = "QR573";
{fltno: QR573, route: BLR-DOH, status: ARRIVED}
eu-west-3>

This update is almost instantaneous, reflected in us-east-2 for the family member there to see (if they happen to be awake at the time!):

eu-west-3> connect us-east-2;
CONNECT
us-east-2> select * from flights where fltno = "QR573";
{fltno: QR573, route: BLR-DOH, status: ARRIVED}
us-east-2>

As you can see, a globally distributed application with data in multiple Regions can operate in a completely active-active way. All of this replication is handled automatically by DynamoDB global tables. Conflict resolution is handled on a last writer wins basis. Data is propagated asynchronously and is eventually consistent.

Let’s assume that you want to add another replica in us-west-2. DynamoDB Shell could do that (another ALTER TABLE invocation). However, DynamoDB Shell also supports the EXPLAIN command, which tells you the API call that is performed:

us-east-2> explain alter table flights add replica us-west-2;
UpdateTable({
   "TableName":   "flights",
   "ReplicaUpdates":   [{
         "Create":   {
            "RegionName":   "us-west-2",
            "TableClassOverride":   "STANDARD"
         }
      }]
})

The explain command is a useful way for new DynamoDB users to learn the DynamoDB API.

Finally, let’s add a replica in us-west-2 but set the table class on the replica to DynamoDB Standard-Infrequent Access (DynamoDB Standard-IA):

us-east-2> alter table flights add replica us-west-2 table class standard infrequent access;
ALTER
us-east-2>

When the command is complete, you have a table in us-west-2 that uses the Standard-IA table class:

us-west-2> describe flights;
Name: flights (ACTIVE)
[…]
Table Class: STANDARD_INFREQUENT_ACCESS
[…]
Replica Region: eu-west-3 (Status: ACTIVE)
Replica Region: ap-south-1 (Status: ACTIVE)
Replica Region: us-east-2 (Status: ACTIVE)
Replica Region: us-west-2 (Status: ACTIVE)
us-west-2>

In this example, you created a table (which was an on-demand or pay-per-request table) in us-east-2 and created two global table replicas in ap-south-1 and eu-west-3 using DynamoDB Shell.

You saw that data that had been inserted in us-east-2 was automatically propagated to the other two replicas. Updates made to the data in any Region are replicated to all Regions.

DynamoDB shell offers the same support for SELECT, INSERT, UPDATE, UPSERT, REPLACE, and DELETE on regional tables and global tables as for local tables. All changes are automatically propagated to all replicas by DynamoDB global tables.

Conclusion

DynamoDB global tables are a powerful construct that allow you to build globally distributed applications. The replication of data is completely managed by DynamoDB and conflict resolution is handled on a “last writer wins” basis. Data is propagated asynchronously and is eventually consistent.

DynamoDB Shell can help you get started with DynamoDB and DynamoDB global tables and explore the features and capabilities that are provided for you in a fully managed database service.

Have you tried DynamoDB Shell? Let us know what features you would like us to support in the shell. To get started with DynamoDB Shell, refer to Query data with DynamoDB Shell – a command line interface for Amazon DynamoDB or follow the instructions in the README.md file in the GitHub repo.

Macintosh users, you can get DynamoDB Shell from homebrew.

brew tap aws/tap
brew install aws-ddbsh

About the author

Amrith Kumar is a Senior Principal Engineer in Amazon Web Services and works on Amazon DynamoDB.