假设你的电商平台同时面向东京、法兰克福和弗吉尼亚的用户,订单数据如果只存放在一个区域,远距离请求的往返延迟可能超过300毫秒。DynamoDB全局表就是为了消除这种地理延迟而生的特性:你可以在多个AWS区域创建同名表,DynamoDB会自动将写入的数据异步复制到其他区域,每个区域的应用程序都能读写本地副本,而不需要手动管理同步逻辑。

创建全局表后,所有副本表共享相同的表名和主键结构,但每个区域拥有独立的数据存储和吞吐容量。写入只会路由到发起请求的本地表,DynamoDB流会捕获变更并传播到远程副本。这个过程通常在一秒内完成,但无法保证强一致性——如果你在东京写入一条记录,法兰克福的读者可能在几百毫秒后才能看到。因此全局表采用的是最终一致性模型,适合那些能容忍短暂数据延迟的应用。
全局表的底层复制机制
要理解全局表为什么能自动同步,必须从DynamoDB Streams说起。当你为表启用流时,DynamoDB会记录每一次写入操作的新旧镜像,全局表内部使用了跨区域的流复制器(Replicator)。这个复制器以几乎实时的方式消费源区域的流记录,然后将变更应用到目标区域的副本表。整个过程由AWS托管,你不需要配置任何消息队列或调度任务。
复制是双向的:任意一个区域接收到的写入都会被广播到其他所有区域。这意味着如果两个客户端几乎同时在不同区域修改同一条记录,就可能产生冲突。DynamoDB采用了一种简单粗暴的冲突解决策略——最后写入者胜出(Last Writer Wins)。具体来说,每个写入操作都会附带一个内部时间戳,当复制器发现目标表上已有一条更新时间更晚的记录时,它会丢弃较早的写入。时间戳基于AWS的区域时钟,但由于无法做到完全同步,冲突解决在极端情况下可能存在偏差,这正是全局表的一个关键设计权衡。
需要特别注意的是,删除操作同样参与冲突解决。如果你在区域A删除了一条记录,稍后区域B的旧写入复制过来时,如果删除操作的时间戳更新,旧写入会被丢弃;反过来,如果旧写入的时间戳比删除操作更晚,那条记录可能会“复活”。因此在设计数据模型时,尽量避免对同一主键进行频繁的跨区域并发修改,或者使用条件写入来降低冲突概率。
创建全局表的完整步骤
创建全局表目前有两种主流方式:AWS管理控制台和AWS CLI。先从CLI开始,因为它更适合自动化。首先你需要在两个(或多个)区域分别创建同名表,并且启用DynamoDB Streams。下面的命令展示了在美东一区(us-east-1)和亚太东北一区(ap-northeast-1)创建相同结构的表:
# 在us-east-1创建表
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions AttributeName=OrderID,AttributeType=S \
--key-schema AttributeName=OrderID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region us-east-1
# 在ap-northeast-1创建同样结构
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions AttributeName=OrderID,AttributeType=S \
--key-schema AttributeName=OrderID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region ap-northeast-1
两张表创建完成后,调用 create-global-table 命令将它们关联成一个全局表。该命令会启动复制进程,并返回全局表的描述信息:
aws dynamodb create-global-table \
--global-table-name Orders \
--replication-group RegionName=us-east-1 RegionName=ap-northeast-1 \
--region us-east-1
如果使用CloudFormation,可以通过 AWS::DynamoDB::GlobalTable 资源一步到位。以下模板片段展示了如何声明一个跨越两个区域的全局表,并启用按需容量模式:
Resources:
GlobalOrdersTable:
Type: AWS::DynamoDB::GlobalTable
Properties:
TableName: Orders
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: OrderID
AttributeType: S
KeySchema:
- AttributeName: OrderID
KeyType: HASH
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
Replicas:
- Region: us-east-1
- Region: ap-northeast-1
创建全局表后,你需要更新应用程序的连接逻辑:每个区域的应用实例应该连接本区域的DynamoDB端点,而不是所有请求都打到同一个区域。例如在东京的ECS容器中使用 https://dynamodb.ap-northeast-1.amazonaws.com 作为endpoint,在弗吉尼亚使用 https://dynamodb.us-east-1.amazonaws.com。这样就能充分发挥就近读写的低延迟优势。
冲突解决策略与生产环境注意事项
正如前面提到的,全局表采用最后写入者胜出,这意味着DynamoDB不会尝试合并两个冲突的写入,也不会保留历史版本。如果你的业务逻辑需要更细粒度的冲突处理,必须在应用层自己做版本控制。例如在订单状态字段中维护一个单调递增的版本号,每次更新时使用条件表达式检查版本号是否匹配,这样可以有效避免远程复制导致的旧值覆盖新值。
全局表对吞吐容量的管理也有特殊要求。如果你在创建表时选择了预置容量模式,每个区域的副本表拥有独立的读写容量单位(RCU/WCU),你需要分别监控和调整各个区域的容量。一旦某个区域的写入突发超出容量,该区域的流复制可能会被节流,导致跨区域同步延迟加大。按需容量模式(PAY_PER_REQUEST)省去了容量规划,但成本可能更高,具体要根据工作负载的特征选择。
另外,全局表目前不支持本地二级索引(LSI)的自动复制,但支持全局二级索引(GSI)。如果你在源表上创建了GSI,该索引会被复制到所有副本区域,并且每个区域的GSI容量也需要独立管理。还有一个限制是:全局表不支持DynamoDB Accelerator (DAX),因为DAX的缓存机制与跨区域复制存在冲突。如果你的应用需要极致读取性能,可以考虑在每个区域分别启用DAX,但要注意DAX缓存失效的传播问题。
故障切换场景下,全局表的优势非常明显。如果某个AWS区域发生长时间不可用,你可以将流量切换到其他区域的副本表,数据仍然可用。但需要注意,由于复制是异步的,故障发生前最后几毫秒的写入可能会丢失,因此全局表并不等同于强一致的多活数据库。在设计跨区域容灾方案时,要明确恢复点目标(RPO)和恢复时间目标(RTO),全局表通常能达到秒级RPO和分钟级RTO,但在极端情况下可能会有数据不一致的窗口。
全局表适用场景与替代方案对比
全局表最适合那些需要低延迟本地读取和写入、且能容忍最终一致性的应用。典型场景包括:多区域用户配置文件、全球商品目录、游戏排行榜(允许短暂不一致)以及跨区域协作工具。如果你的业务要求严格的强一致性,比如金融交易账本或多区域库存扣减,全局表可能不够安全,应该考虑其他方案,比如在单个区域内使用DynamoDB事务,或者借助Aurora Global Database等提供更强一致性保证的服务。
与Aurora Global Database相比,DynamoDB全局表是全托管的NoSQL方案,扩展性更好,但一致性模型更弱。Aurora全局数据库支持跨区域读取副本,写入仍然只能发生在主区域,因此在跨区域写入方面不如DynamoDB灵活。另一种常见的替代是自建Cassandra多数据中心集群,虽然一致性可调,但运维复杂度极高。全局表的价值在于把多区域复制的复杂性完全交给AWS管理,开发者只需关注数据模型和冲突策略。
从成本角度看,全局表会产生跨区域数据传输费用。每次写入复制到其他区域时,都会按照AWS的跨区域数据传输定价计费。如果写入频繁且数据量大,这笔开销可能相当可观。你可以通过减少不必要的属性、优化写入模式(例如批量写入)来降低传输成本。同时,每个区域的副本表也会单独计费存储和吞吐,所以整体成本大约是单区域表的区域数量倍加上传输费。在评估是否引入全局表时,务必用实际工作负载进行成本测算。
DynamoDB全局表多区域复制分布式数据库修改时间:2026-10-02 01:12:57