高级阅读约 2 分钟

DynamoDB Global Tables:多区域复制详解

一个 全局表 是一张跨多个 AWS 区域复制的 DynamoDB 表,其中每个副本都可写。DynamoDB 自动让它们保持同步——你在每个区域都得到低延迟的本地读写,外加跨区域的灾难恢复,而不必自己运行复制。

在这个审计日志场景里,一个欧盟客户要求他们的数据存放在 eu-west-1,而其余部分跑在 us-east-1。而作为一份对合规至关重要的日志,它需要挺过一次完整的区域性中断。一个全局表用一个特性同时回答了这两点。

DynamoDB 全局表是怎么工作的?

DynamoDB 全局表是一张跨多个 AWS 区域复制的表,其中每个副本都可读可写。DynamoDB 通过 的异步复制自动同步它们,以上次写入者获胜来解决冲突。你在每个区域都得到低延迟的本地读写,外加跨区域的灾难恢复,撑起 DynamoDB 的 99.999% 可用性 SLA。

  • 多区域、双活。 每个副本都完全可读可写;任何区域的写入都会传播到其他区域。
  • 在默认模式下,复制是异步且 跨区域——通常在一秒内,但不是即时的。(还存在一个强一致模式——见下文。)
  • 冲突以上次写入者获胜来解决。 在两个区域对同一个项的并发写入会调和为最近的那一个。
  • 它撑起 99.999% 可用性 SLA——一张多区域全局表是 DynamoDB 可用性最高的配置。

问题:一个区域不够

一张单区域表有两个审计日志无法接受的限制。第一,数据驻留:一个欧盟客户的事件必须存储在欧盟,但你的应用跑在美国。第二,灾难恢复:如果 us-east-1 发生中断,一份单区域审计日志在整个持续期间既读不了也写不了——恰恰在你最需要那份“发生了什么”的记录的时候。

自己去搭这两样中的任何一样——跨区域复制、故障切换、冲突处理——都是一个庞大而易出错的工程。全局表把它变成一个配置选择。

复制机制

你给表 添加一个副本区域;DynamoDB 在那里创建一份副本,并让所有副本保持同步。

有两条一致性规则定义了默认(MREC)行为:

  • 跨区域复制是异步的。us-east-1 的一次写入在本地被确认,然后传播到 eu-west-1——通常在一秒内,但另一个区域在一次写入之后紧接着的一次读取可能还看不到它。(在默认的 MREC 模式下,强 仍然工作,但只在单个区域 内部。)
  • 冲突以上次写入者获胜。 如果同一个项在两个区域几乎同时被写入,DynamoDB 保留时间戳最新的那次写入,丢弃另一个。
异步复制 ~1us-east-1audit-log 副本(读 + 写)eu-west-1audit-log 副本(读 + 写)

一个实战示例:一个同时也是灾备的欧盟副本

你把 eu-west-1 添加为审计日志表的一个副本。现在:

write regionitemvisible in
us-east-1TENANT#acmeEVENT#…#a1both regions (~1s lag to EU)
eu-west-1TENANT#bmwEVENT#…#e7both regions (~1s lag to US)

欧盟客户的应用向本地的 eu-west-1 副本写入并从中读取——低延迟且数据驻留在区域内。满足驻留的那同一份复制也兼作 灾难恢复:如果 us-east-1 宕机,eu-west-1 副本仍持有完整的日志并提供流量;你把故障切换到它。

因为这份审计日志是 只追加且按租户分区的,上次写入者获胜在这里基本不是问题——某个租户的事件都从一个区域写入,且事件键是唯一的,所以两个区域很少在同一个项上竞态。这不是运气;这正是为什么一份只追加日志是全局表最干净的契合场景之一。相比之下,一个可变的计数器在并发的跨区域写入下就需要小心对待。

在 DynoTable 中操作

添加一个副本之后,你想确认数据确实落到了新区域并与源匹配——欧盟副本真的持有 acme 的事件、属性正确,而且没有滞后。

DynoTable 用各自的凭据连接到任何区域,所以你可以把一个窗口指向 us-east-1,把另一个指向 eu-west-1,并排比较同一个租户的项来验证复制。

在 DynoTable 中验证 us-east-1 副本——acme 的审计事件,按租户查询。
在 DynoTable 中验证 us-east-1 副本——acme 的审计事件,按租户查询。

你可以在 DynamoDB 表达式构建器 里原型化你将对每个副本运行的按区域查询。

陷阱与后续步骤

  • 别跨区域读你自己写的。 复制滞后意味着一个区域的一次写入可能有约一秒不出现在另一个区域里。别在美国写入然后立即从欧盟读取还指望看到它。在默认的 MREC 模式下,强一致读取只在单个区域内工作;MRSC 把强读取扩展到跨区域。
  • 上次写入者获胜会悄无声息地丢数据。 对于在两个区域并发写入的可变项,失败者被丢弃,没有错误。只追加或每项单写入者的设计(就像这份审计日志)避开了这个问题;共享的可变状态需要一个感知冲突的设计。
  • 每个副本都要花钱。 每个区域存储一份完整副本,并为它自己的容量和存储计费——一个副本大致让成本翻倍。为真实的驻留或灾备需求添加区域,而不是默认就加。
  • 备份是按副本的。 一张恢复出来的全局表会成为一张独立的表——按区域规划恢复。参见 备份与时间点恢复

全局表防的是丢掉一个区域。最后一个运维关切是防止丢掉 数据——一次糟糕的部署或一次误删——用 备份与时间点恢复

下载 DynoTable,连接到多个区域,验证你的全局表副本持有相同的数据。

更新于