使用 Azure Cosmos DB 实现高可用性

适用对象: NoSQL MongoDB Cassandra Gremlin

要生成高度可用的解决方案,必须评估其所有组件的可靠性特征。 Azure Cosmos DB 提供功能和配置选项以帮助实现解决方案的高可用性。

本文使用了以下术语:

  • 恢复时间目标(RTO):影响 Azure Cosmos DB 的中断开始到恢复到完全可用性之间的时间。
  • 恢复点目标(RPO):正确还原的最后一次写入与影响 Azure Cosmos DB 的中断开始之间的时间。

注意

预期和最大 RPO 和 RTO 取决于 Azure Cosmos DB 所经历的中断类型。 例如,单个节点的中断具有与整个区域中断不同的预期 RTO 和 RPO。

本文详细介绍了可能影响 Azure Cosmos DB 可用性的事件以及相应的 Azure Cosmos DB 配置选项。

副本维护

Azure Cosmos DB 是一项多租户服务,可透明地管理各个计算节点的所有详细信息。 用户不必担心任何类型的修补或计划内维护。 Azure Cosmos DB 通过系统执行的所有自动维护操作来保证 可用性的 SLA 和 P99 延迟。

副本中断

副本中断 指的是部署在 Azure 区域中的 Azure Cosmos DB 群集中各个节点的中断。

Azure Cosmos DB 保证四个副本仲裁内的帐户的每个 Azure 区域中至少有三个数据副本,从而自动缓解副本中断。 对于单个节点中断,此保证会使 RTO 为 0,RPO 为 0,无需更改或配置应用程序。

在许多 Azure 区域中,可以跨 可用性区域 分发 Azure Cosmos DB 群集。 可用性区域可以增加 SLA,因为它们在物理上独立存在,并提供不同的电源、网络和冷却。 使用可用性区域部署 Azure Cosmos DB 帐户时,Azure Cosmos DB 会提供 RTO (0)和 RPO (0),即使在区域中断的情况下也是如此。

在单个 Azure 区域中部署时,无需额外的用户输入,Azure Cosmos DB 可以灵活应对节点中断。 跨可用性区域启用冗余使 Azure Cosmos DB 能够灵活应对区域中断,但代价是 费用 会增加。

只有向 Azure Cosmos DB 帐户添加新区域时,才能配置区域冗余。 对于现有区域,要启用区域冗余,可以先删除该区域,重新添加时再启用区域冗余。 对于单区域帐户,此方法需要添加区域以作为暂时的故障转移目标,然后删除并重新添加所需区域,并同时启用区域冗余。

默认情况下,Azure Cosmos DB 帐户不使用多个可用性区域。 可以通过以下方式跨多个可用性区域启用部署:

如果 Azure Cosmos DB 帐户分布在 N 个 Azure 区域之间,则所有数据至少有 N x 4 个副本。 有关 Azure Cosmos DB 如何在每个区域中复制数据的详细信息,请参阅使用 Azure Cosmos DB 进行多区域分发。 在两个以上的区域中拥有 Azure Cosmos DB 帐户可提高应用程序的可用性,且关联区域之间的延迟较低。

区域中断

区域中断 指的是跨所有可用性区域影响 Azure 区域中所有 Azure Cosmos DB 节点的中断。 对于极少数区域中断的情况,可以将 Azure Cosmos DB 配置为支持持续性和可用性的各种结果。

持续性

当在单个区域中部署 Azure Cosmos DB 帐户时,通常不会发生数据丢失。 在受影响的区域中恢复 Azure Cosmos DB 服务后,会还原数据访问。 只有在 Azure Cosmos DB 区域发生不可恢复的灾难时,才可能发生数据丢失。

为了帮助防止区域中的毁灭性灾难可能导致数据完全丢失,Azure Cosmos DB 提供了两种备份模式:

  • 连续备份 每 100 秒备份一次每个区域。 它们使你能够以 1 秒的粒度将数据还原到任何时间点。 在每个区域,备份取决于该区域提交的数据。
  • 定期备份,从帐户下的所有容器完全备份所有分区,不跨分区同步。 最小备份间隔为 1 小时。

在多个区域中部署 Azure Cosmos DB 帐户时,数据持续性取决于在该帐户上配置的一致性级别。 对于所有一致性级别,下表详细说明了在至少两个区域中部署的 Azure Cosmos DB 帐户的 RPO。

一致性级别 区域中断的 RPO
会话一致性、一致性前缀或最终一致性 少于 15 分钟
有限过期性 KT
0

K = 某项的版本(即更新)数。

T = 自上次更新以来的时间间隔。

对于多区域帐户,KT 的最小值为 100,000 次写入操作或 300 秒。 此值定义了使用有限过期时数据的最小 RPO。

有关一致性级别之间差异的详细信息,请参阅 Azure Cosmos DB 中的一致性级别

可用性

如果解决方案需要在区域中断期间保持持续可用性,可以将 Azure Cosmos DB 配置为跨多个区域复制数据,并在需要时透明地故障转移到可用区域。

发生区域性服务中断时,单区域帐户的可用性可能会损失。 要确保始终保持高可用性,建议设置具有 单写入区域和至少第二个(读取)区域 的 Azure Cosmos DB 帐户并启用 服务托管故障转移

服务托管故障转移允许 Azure Cosmos DB 对多区域帐户的写入区域进行故障转移,从而以数据丢失为代价来保持可用性,如前面的 持续性 部分所述。 区域故障转移在 Azure Cosmos DB 客户端中进行检测和处理。 它们不需要在应用程序中进行任何更改。 有关如何启用多个读取区域和服务托管故障转移的说明,请参阅 使用 Azure 门户管理 Azure Cosmos DB 帐户

重要

强烈建议将用于生产工作负载的 Azure Cosmos DB 帐户配置为 启用服务托管故障转移。 此配置支持 Azure Cosmos DB 将帐户数据库故障转移到可用区域。 如果没有此配置,则在写入区域服务中断的整个持续时间内,帐户会遇到写入可用性损失的情况。 由于缺少区域连接,手动故障转移不会成功。

警告

即使启用了服务管理的故障转移,部分服务中断也可能需要 Azure Cosmos DB 服务团队进行手动干预。 在这些情况下,故障转移可能需要长达 1 小时(或更长时间)才能生效。 为了在部分服务中断期间提高写入可用性,除了服务管理的故障转移之外,我们还建议启用可用性区域。

多个写入区域

可以将 Azure Cosmos DB 配置为接受多个区域内的写入。 此配置有助于减少地理分散式应用程序中的写入延迟。

为多个写入区域配置 Azure Cosmos DB 帐户时,不支持强一致性,可能会出现写入冲突。 有关如何解决这些冲突的详细信息,请参阅 使用多个写入区域时的冲突类型和解决策略

重要

鉴于内部 Azure Cosmos DB 体系结构,使用多个写入区域不能保证区域中断期间的写入可用性。 在区域中断期间实现高可用性的最佳配置是启用了服务托管故障转移的单写入区域。

冲突解决区域

当 Azure Cosmos DB 帐户配置了多区域写入时,其中一个区域将充当写入冲突中的仲裁者。

多区域写入的最佳做法

下面是写入多个区域时要考虑的一些最佳做法。

将本地流量保留在本地

使用多区域写入时,应用程序应严格向本地 Cosmos DB 区域发出源自本地区域的读写流量。 为了获得最佳性能,请避免跨区域调用。

应用程序必须避免以下反模式以最大程度地减少冲突:

  • 将相同的写入操作发送到所有区域,从而提高获得快速响应时间的几率

  • 根据每个请求随机确定读取或写入操作的目标区域

  • 使用轮循机制策略根据每个请求确定读取或写入操作的目标区域

避免依赖复制延迟

无法为强一致性配置多区域写入帐户。 在 Azure Cosmos DB 在本地复制数据后,写入的区域会立即响应,同时以异步方式多区域复制数据。

虽然不常见,但在异地复制数据时,一个或几个分区上可能会发生复制延迟。 复制延迟可能是由于网络流量中的罕见波动或冲突解决率高于平常导致。

例如,应用程序写入区域 A 但从区域 B 读取的体系结构引入了对两个区域之间复制延迟的依赖。 但是,如果应用程序读取和写入同一区域,即使存在复制延迟,性能也会保持不变。

评估写入操作的会话一致性使用情况

在会话一致性中,使用会话令牌执行读写操作。

对于读取操作,Azure Cosmos DB 会将缓存的会话令牌发送到服务器,保证接收与指定(或较新)会话令牌相对应的数据。

对于写入操作,Azure Cosmos DB 会将会话令牌发送到数据库,保证只在服务器已赶上提供的会话令牌时保留数据。 在单区域写入帐户中,始终保证写入区域已赶上会话令牌。 但是,在多区域写入帐户中,写入的区域可能没有赶上向另一个区域发出的写入。 如果客户端使用来自区域 B 的会话令牌写入区域 A,在赶上区域 B 中所做的更改之前,区域 A 将无法保留数据。

在客户端实例之间传递会话令牌时,最好仅将会话令牌用于读取操作而非写入操作。

缓解对同一文档的快速更新

当重复更新同一文档时,服务器用于解决或确认不存在冲突的更新可能会与应用程序触发的写入发生冲突。 在解决冲突期间,对同一文档的连续快速重复更新会导致更高的延迟。

虽然重复更新同一文档中的偶尔突发不可避免,但如果稳定状态流量在较长时间内看到对同一文档的快速更新,可以考虑改为探索新建文档的体系结构。

区域中断期间预计发生的情况

在服务还原之前,单区域帐户的客户端会遇到读写可用性损失的情况。

多区域帐户会经历不同的行为,具体取决于以下配置和中断类型。

配置 中断 可用性影响 持续性影响 要执行的操作
单个写入区域 读取区域中断 所有客户端都会自动将读取重定向到其他区域。 对于所有配置,读取或写入可用性不会损失。 例外是配置两个具有强一致性的区域,在还原服务之前,这些区域的写入可用性会损失。 或者,如果启用服务托管故障转移,服务会将区域标记为失败,并发生故障转移。 无数据丢失。 在中断期间,请确保剩余区域中预配了足够的请求单位(RU)以支持读取流量。

当中断结束时,请根据需要重新调整预配的 RU。
单个写入区域 写入区域中断 客户端会将读取重定向到其他区域。

如果未启用服务托管故障转移,客户端会遇到写入可用性损失的情况。 中断结束时,会自动还原写入可用性。

如果启用了服务托管故障转移,在服务将故障转移管理到选择的新写入区域之前,客户端会遇到写入可用性损失的情况。
如果未选择强一致性级别,服务可能不会将一些数据复制到剩余的活动区域。 此复制取决于所选的 一致性级别。 如果受影响的区域遭受永久性数据丢失,你可能会丢失未复制的数据。 在中断过程中,请确保剩余区域中预配了足够的 RU 以支持读取流量。

不要 在中断期间触发手动故障转移,因为它不会成功。

当中断结束时,请根据需要重新调整预配的 RU。 使用适用于 NoSQL 的 API 的帐户也可能从 冲突源 恢复失败区域中的未复制数据。
多个写入区域 任何区域中断 写入可用性可能会暂时损失,这类似于启用了服务托管故障转移的单写入区域。 如果中断时发生大量冲突写入,冲突解决区域 的故障转移还可能导致写入可用性损失。 失败区域中最近更新的数据可能在剩余的活跃区域中不可用,具体取决于所选的 一致性级别。 如果受影响的区域遭受永久性数据丢失,可能会丢失未复制的数据。 在中断过程中,请确保剩余区域中预配了足够的 RU 以支持更多流量。

中断结束时,可以根据需要重新调整预配的 RU。 如果可能,Azure Cosmos DB 会自动恢复失败区域中的非复制数据。 此自动恢复使用为使用适用于 NoSQL 的 API 的帐户配置的冲突解决方法。 对于使用其他 API 的帐户,此自动恢复使用 最后写入胜出

有关读取区域中断的其他信息

  • 断开受影响区域的连接,并将其标记为脱机。 Azure Cosmos DB SDK 会将读取调用重定向到首选区域列表中的下一个可用区域。

  • 如果首选区域列表中无可用区域,调用会自动回退到当前的写入区域。

  • 处理读取区域服务中断不需要对应用程序代码进行更改。 受影响的读取区域重新联机后,它会自动与当前写入区域同步,并在完全回复后再次可用于处理读取请求。

  • 后续的读取会重定向到恢复的区域,不需更改应用程序代码。 在故障转移和重新加入上一个失败的区域期间,Azure Cosmos DB 会继续遵循读取一致性保证。

  • 即使在发生了 Azure 区域永久无法恢复的罕见不幸事件中,如果为多区域 Azure Cosmos DB 帐户配置了强一致性,也不会丢失数据。 多区域 Azure Cosmos DB 帐户具有前面 持续性部分指定的持续性特征。

有关写入区域中断的其他信息

  • 在写入区域中断期间,如果在 Azure Cosmos DB 帐户上配置了服务托管故障转移,则 Azure Cosmos DB 帐户会将次要区域提升为新的主要写入区域。 会按你指定的区域优先级顺序故障转移到其他区域。

  • 不应触发手动故障转移,这在存在源或目标区域中断时不会成功。 原因是故障转移过程包括一致性检查,要求在区域之间建立连接。

  • 当上一个受影响的区域重新联机时,可以通过 冲突源 使用该区域失败时未复制的任何写入数据。 应用程序可以读取冲突源,根据特定于应用程序的逻辑解决冲突,并根据需要将更新后的数据写回 Azure Cosmos DB 容器。

  • 在之前受影响的写入区域恢复后,它会在 Azure 门户中显示为“联机”,可用作读取区域。 目前可以使用 PowerShell、Azure CLI 或 Azure 门户切换回恢复的区域作为写入区域。 在切换写入区域之前、期间或之后,数据或可用性都不会丢失。 应用程序仍然高度可用。

警告

如果写入区域出现故障,而 Azure Cosmos DB 帐户通过服务托管的故障转移将次要区域提升为新的主要写入区域,那么原始写入区域将不会在恢复后自动回升为写入区域。 你有责任使用 PowerShell、Azure CLI 或 Azure 门户切回恢复的区域作为写入区域(在安全的情况下,如上所述)。

SLA

下表总结了各种帐户配置的高可用性功能:

KPI 无可用性区域的单区域写入 有可用性区域的单区域写入 有或无可用性区域的多区域、单区域写入 有可用性区域的多区域、单区域写入 无可用性区域的多区域、单区域写入
写入可用性 SLA 99.99% 99.995% 99.99% 99.995% 99.999%
读取可用性 SLA 99.99% 99.995% 99.999% 99.999% 99.999%
区域故障:数据丢失 数据丢失 无数据丢失 无数据丢失 无数据丢失 无数据丢失
区域故障:可用性 可用性缺失 无可用性缺失 无可用性缺失 无可用性缺失 无可用性缺失
区域中断:数据丢失 数据丢失 数据丢失 取决于一致性级别。 有关详细信息,请参阅一致性、可用性和性能权衡 取决于一致性级别。 有关详细信息,请参阅一致性、可用性和性能权衡 取决于一致性级别。 有关详细信息,请参阅一致性、可用性和性能权衡
区域中断:可用性 可用性缺失 可用性缺失 读取区域故障没有可用性缺失,写入区域故障有暂时缺失 读取区域故障没有可用性缺失,写入区域故障有暂时缺失 受影响区域内无读取可用性损失、临时写入可用性损失
价格 (1) 不适用 预配 RU/秒 x 1.25 速率 预配的 RU/秒 x N 个区域 预配的 RU/秒 x 1.25 速率 x N 个区域(2 多区域写入速率 x N 个区域

1 对于无服务器帐户,RU 乘以系数 1.25。

2 1.25 速率仅适用于启用可用性区域的区域。

有关生成高可用性应用程序的提示

  • 了解事件期间 Azure Cosmos SDK 的预期行为 以及影响它的配置。

  • 要确保高写入和读取可用性,请将 Azure Cosmos DB 帐户配置为跨越至少两个区域(或三个区域 - 如果使用强一致性)。 若要了解详细信息,请参阅教程:使用 API for NoSQL 设置 Azure Cosmos DB 多区域分布

  • 对于配置了单写入区域的多区域 Azure Cosmos DB 帐户,请 使用 Azure CLI 或 Azure 门户启用服务托管故障转移。 启用服务托管故障转移后,每当发生区域性灾难时,Azure Cosmos DB 都会对帐户进行故障转移,无需任何用户输入。

  • 即使 Azure Cosmos DB 帐户高度可用,应用程序也不一定能够正常保持高可用性。 要测试应用程序的端到端高可用性,请在应用程序测试或灾难恢复(DR)演练过程中,暂时禁用帐户的服务托管故障转移。 使用 PowerShell、Azure CLI 或 Azure 门户调用手动故障转移,然后监视应用程序。 完成测试后,可以故障回复到主要区域,并还原该帐户的服务托管故障转移。

    重要

    在源或目标区域发生 Azure Cosmos DB 中断期间,不要调用手动故障转移。 手动故障转移需要区域连接才能保持数据一致性,因此不会成功。

  • 在多区域分布式数据库环境中,当发生区域范围的服务中断时,一致性级别与数据持续性之间存在直接关系。 制定业务连续性计划时,需要了解在中断事件发生后,应用程序完全恢复之前的最大可接受时间(即 RTO)。 还需要了解在中断事件发生后,应用程序在恢复时可忍受最近数据更新丢失的最长期限(即 RPO)。 有关 RTO 和 RPO 的详细信息,请参阅 Azure Cosmos DB 中的一致性级别

Azure Cosmos DB 区域中断期间可能发生的情况

对于单区域帐户,在 Azure Cosmos DB 区域中断期间,客户端会遇到读写可用性损失的情况。 多区域帐户会经历不同的行为,如下表所述。

写入区域 服务托管故障转移 期望 要执行的操作
单个写入区域 未启用 如果在未使用强一致性时读取区域内发生中断,所有客户端会重定向到其他区域。 读取或写入可用性不会损失,数据也不会丢失。 使用强一致性时,如果剩余的读取区域少于两个,则读取区域中断可能会影响写入可用性。

如果写入区域发生中断,客户端会遇到写入可用性损失的情况。 如果未选择强一致性,服务可能不会将一些数据复制到剩余的活动区域。 此复制取决于所选的 一致性级别。 如果受影响的区域遭受永久性数据丢失,可能会丢失未复制的数据。

当中断结束时,Azure Cosmos DB 将自还原写入可用性。
在中断过程中,请确保剩余区域中预配了足够的 RU 以支持读取流量。

不要 在中断期间触发手动故障转移,因为它不会成功。

当中断结束时,请根据需要重新调整预配的 RU。
单个写入区域 已启用 如果在未使用强一致性时读取区域内发生中断,所有客户端会重定向到其他区域。 读取或写入可用性不会损失,数据也不会丢失。 使用强一致性时,如果剩余的读取区域少于两个,读取区域中断可能会影响写入可用性。

如果写入区域发生中断,则在 Azure Cosmos DB 根据你的首选项选择新的区域作为新写入区域前,客户端会遇到写入可用性损失的情况。 如果未选择强一致性,服务可能不会将一些数据复制到剩余的活动区域。 此复制取决于所选的 一致性级别。 如果受影响的区域遭受永久性数据丢失,可能会丢失未复制的数据。
在中断过程中,请确保剩余区域中预配了足够的 RU 以支持读取流量。

不要 在中断期间触发手动故障转移,因为它不会成功。

中断结束时,可以将写入区域移回原始区域,并根据需要重新调整预配的 RU。 使用适用于 NoSQL 的 API 的帐户也可能从 冲突源 恢复失败区域中的未复制数据。
多个写入区域 不适用 失败区域中最近更新的数据可能在剩余的活跃区域中不可用。 最终一致性、一致性前缀和会话一致性级别可保证过期时间少于 15 分钟。 根据配置的不同,有限过期可保证更新次数少于 K或时间少于 T 秒。 如果受影响的区域遭受永久性数据丢失,可能会丢失未复制的数据。 在中断过程中,请确保剩余区域中预配了足够的 RU 以支持更多流量。

中断结束时,可以根据需要重新调整预配的 RU。 如果可能,Azure Cosmos DB 会恢复失败区域中的未复制数据。 此自动恢复使用为使用适用于 NoSQL 的 API 的帐户配置的冲突解决方法。 对于使用其他 API 的帐户,此恢复使用最后写入有效

后续步骤

接下来,可以阅读以下文章: