使用 DynamoDB 全局表撤离区域 - Amazon DynamoDB

使用 DynamoDB 全局表撤离区域

撤离区域是将读取和写入活动从该区域中迁移出去的过程。这通常是写入活动,有时是读取活动。

撤离实时区域

您可能出于多种原因决定撤离实时区域。撤离可能是日常业务活动的一部分,例如,如果您使用的是“全天候式”(follow-the-sun)写入一个区域模式。撤离也可能是由于商业方面的决策要求更改当前主动区域,以应对 DynamoDB 外部软件堆栈的故障,或者因为您遇到了一般性问题,如区域内的延迟高于正常情况。

写入任何区域模式下,撤出实时区域很简单。您可以通过任何路由系统将流量路由到备用区域,并让已在已撤离区域中发生的写入操作照常复制。

写入一个区域写入您的区域模式下,在新的主动区域中开始写入之前,必须确保已对主动区域的所有写入进行完全记录、流处理和全局传播。这一点是必需的,用于确保将来的写入是针对最新版本的数据。

假设区域 A 处于主动状态,区域 B 处于被动状态(无论是对于整个表,还是对于以区域 A 为主区域的项目)。执行撤离的典型机制是暂停对 A 的写入操作,等待足够长的时间让这些操作完全传播到 B,更新架构堆栈以识别 B 处于主动状态,然后恢复对 B 的写入操作。没有任何指标可以绝对肯定地表明区域 A 已将其数据完全复制到区域 B。如果区域 A 运行状况正常,暂停对区域 A 的写入操作并等待 ReplicationLatency 指标的最近最大值的 10 倍,通常足以确定复制完成。如果区域 A 运行状况不佳且显示延迟增加的其他区域,则应为等待时间选择更大的倍数。

撤离离线区域

有一个特殊情况需要考虑:如果区域 A 在没有通知的情况下完全离线,会怎样? 这极不可能,但仍需谨慎考虑。如果发生这种情况,则区域 A 中尚未传播的任何写入操作都将保留,并在区域 A 恢复在线后进行传播。写入操作不会丢失,但它们的传播会被无限期延迟。

在这种情况下,如何继续操作将由应用程序决定。为了实现业务连续性,写入操作可能需要继续指向新的主区域 B。但是,如果区域 B 中的某个项目收到更新,而针对该项目的写入操作有来自区域 A 的挂起传播,则在以最后写入者为准模型下,该传播将被抑制。区域 B 中的任何更新都可能抑制传入的写入请求。

写入任何区域模式下,可以在区域 B 中继续读取和写入,同时相信区域 A 中的项目最终会传播到区域 B,并认识到在区域 A 恢复在线之前可能会丢失项目。如果可能,您应考虑重播新近的写入流量(例如,使用上游事件源),以填补任何可能缺失的写入操作的空白,并让以最后写入者为准冲突解决方案抑制传入写入操作的最终传播。

对于其他写入模式,您必须考虑在多大程度上可以继续工作,而对工作环境的看法稍微过时。在区域 A 恢复在线之前,将丢失一些持续时间很短的写入操作(由 ReplicationLatency 跟踪)。业务能否向前推进? 在某些使用案例中可以向前推进,但在另一些使用案例中,如果没有额外的缓解机制,则可能不行。

例如,假设您需要保持可用的信贷余额,即使在区域出现故障之后也是如此。您可以将余额拆分为两个不同的项目,一个位于主区域 A 中,另一个位于区域 B 中,每个项目从可用余额的一半开始。这将使用写入您的区域模式。在每个区域中处理的事务性更新将写入余额的本地副本。如果区域 A 变为完全离线,则仍然可以在区域 B 中继续进行事务处理,写入操作将仅限于区域 B 中持有的余额部分。当余额变低或必须重新计算信贷余额时,像这样拆分余额会带来复杂性,但它确实提供了一个安全业务恢复的示例,即使存在不确定的待处理写入操作。

再举一个例子,假设您正在捕获 Web 表单数据。您可以使用乐观并发控制(OCC)为数据项目分配版本,并将最新版本作为隐藏字段嵌入到 Web 表单中。在每次提交时,只有当数据库中的版本仍然与构建表单所依据的版本相匹配时,写入操作才会成功。如果版本不匹配,则可以根据数据库中的当前版本刷新(或谨慎合并)Web 表单,然后用户可以再次继续。OCC 模型通常可以防止其他客户端覆盖并生成新版本的数据,但它也可以在失效转移期间提供帮助,此时客户端可能会遇到更旧版本的数据。

假设您使用时间戳作为版本。假设表单最初是在 12:00 针对区域 A 构建的,但是(失效转移后)尝试写入区域 B 并注意到数据库中的最新版本是 11:59。在这种情况下,客户端可以等待 12:00 版本传播到区域 B,然后在该版本之上进行写入;也可以在 11:59 上构建并创建新的 12:01 版本(写入后,该版本将在区域 A 恢复后抑制传入版本)。

最后一个例子是,一家金融服务公司在 DynamoDB 数据库中保存有关客户账户及其金融交易的数据。如果区域 A 完全中断,他们希望确保与其账户相关的任何写入活动在区域 B 中完全可用,或者希望将他们的账户作为已知的部分账户进行隔离,直到区域 A 恢复在线。他们没有暂停所有业务,而是决定只对他们确定有未传播交易的一小部分账户暂停业务。为了实现这一点,他们使用了第三个区域,我们称为区域 C。在他们处理区域 A 中的任何写入操作之前,他们在区域 C 中简要地汇总了那些待处理的操作(例如,一个账户的新交易数量)。这个摘要足以让区域 B 确定其视图是否完全是最新的。从在区域 C 中写入操作,到区域 A 接受写入操作并且区域 B 收到写入操作之前,此操作实际上锁定了该账户。除非作为失效转移过程的一部分,否则不会使用区域 C 中的数据,之后,区域 B 可以将其数据与区域 C 进行交叉核对,以检查其账户是否已过期。在区域 A 恢复将部分数据传播到区域 B 之前,这些账户将被标记为已隔离。

如果区域 C 出现故障,则可以启动一个新的区域 D 以供使用。区域 C 中的数据非常短暂,几分钟后,区域 D 将具有足够新的动态写入操作记录,这将非常有用。如果区域 B 出现故障,区域 A 可以继续接受与区域 C 合作的写入请求。这家公司愿意接受延迟更高的写入(写入到两个区域:C,然后是 A),并且很幸运有了一个可以简洁汇总账户状态的数据模型。