Azure Cosmos DB 中的一致性级别

适用对象: NoSQL MongoDB Cassandra Gremlin

依赖于复制实现高可用性和/或低延迟的分布式数据库必须在 PACELC 定理定义的读取一致性、可用性、延迟和吞吐量之间进行基本权衡。 非常一致性模型的可线性化是数据可编程性的黄金标准。 但是,由于数据必须跨远距离进行复制和提交,因此写入延迟较高,从而增加了高昂的成本。 由于数据无法在每个区域中复制和提交,因此非常一致性也可能因(故障期间)可用性降低而受到影响。 最终一致性提供了更高的可用性和更好的性能,但编写应用程序会更困难,因为数据可能不会在所有区域一致。

目前市场上大多数商业用途的分布式 NoSQL 数据库只能提供非常一致性和最终一致性。 Azure Cosmos DB 提供五个妥善定义的级别。 按最强到最弱的顺序,级别分别为:

有关默认一致性级别的详细信息,请参阅配置默认一致性级别覆盖默认一致性级别

每个级别在可用性与性能方面各有利弊。 下图以范围区间形式显示了不同的一致性级别。

范围区间形式的一致性示意图,以“非常一致”开始,到更高的可用性和吞吐量以及更低的延迟,再到“最终一致性”。

一致性级别和 Azure Cosmos DB API

Azure Cosmos DB 为常用数据库提供对与线路协议兼容的 API 的本机支持。 这些包括 MongoDB、Apache Cassandra、Apache Gremlin 和 Azure 表存储。 在 API for Gremlin 或 API 表存储中,使用 Azure Cosmos DB 帐户上配置的默认一致性级别。 有关 Apache Cassandra 与 Azure Cosmos DB 之间的一致性级别映射的详细信息,请参阅 API for Cassandra 一致性映射。 有关 MongoDB 与 Azure Cosmos DB 之间的一致性级别映射的详细信息,请参阅 API for MongoDB 一致性映射

读取一致性的范围

读取一致性适用于逻辑分区范围内的单个读取操作。 远程客户端、存储过程或触发器可以发出读取操作。

配置默认一致性级别

随时都可在 Azure Cosmos DB 帐户中配置默认的一致性级别。 在帐户中配置的默认一致性级别适用于该帐户下的所有 Azure Cosmos DB 数据库和容器。 针对某个容器或数据库发出的所有读取和查询默认使用指定的一致性级别。 更改帐户级别的一致性时,请确保重新部署应用程序并进行任何必要的代码修改,以便应用这些更改。 有关详细信息,请参阅如何配置默认一致性级别。 还可以覆盖特定请求的默认一致性级别,若要了解详细信息,请参阅如何覆盖默认一致性级别一文。

提示

替代默认一致性级别的操作仅适用于 SDK 客户端中的读取。 默认情况下,配置为非常一致性的帐户仍会将数据同步写入和复制到帐户中的所有区域。 SDK 客户端实例或请求使用会话或较弱一致性替代此级别时,将使用单个副本执行读取。 有关详细信息,请参阅一致性级别和吞吐量

重要

更改默认的一致性级别后,需要重新创建任何 SDK 实例。 这可以通过重启应用程序来完成。 这可确保 SDK 使用新的默认一致性级别。

与一致性级别关联的保证

Azure Cosmos DB 可保证 100% 的读取请求满足所选一致性级别的一致性保证。 azure-cosmos-tla GitHub 存储库中提供了 Azure Cosmos DB 中使用 TLA+ 规范语言精确定义的五个一致性级别。

以下部分描述了五个一致性级别的语义。

非常一致性

非常一致性提供可线性化保证。 可线性化是指并发处理请求。 保证读取操作返回项的最新提交版本。 客户端永远不会看到未提交或不完整的写入。 始终保证用户读取最新确认的写入。

下图以乐谱形式演示了非常一致性。 将数据写入“中国北部 2”区域后,当你从其他区域读取这些数据时,将会获得最新的值:

动画使用音符演示始终同步的非常一致性级别。

动态仲裁

在正常情况下,对于具有强一致性的帐户,当所有区域都确认该记录已复制到此帐户时,此写入才被视为已提交。 但是,对于具有 3 个或更多区域(包括写入区域)的帐户,在某些区域无响应或响应缓慢的情况下,系统可以将区域的仲裁“降档”至全局多数。 此时,无响应区域会从仲裁区域集中取出,以保持强一致性。 仅当它们与其他区域保持一致且按预期运行后,才会重新添加它们。 可从仲裁集中取出的区域数将取决于区域总数。 例如,在一个 3 或 4 区域的帐户中,“多数”分别为 2 个或 3 个区域,因此在其中任一情况下都只能删除 1 个区域。 对于一个 5 区域的帐户,“多数”为 3,因此最多可以删除 2 个无响应区域。 此功能称为“动态仲裁”,可以改善具有 3 个或更多区域的帐户的写入可用性和复制延迟。

注意

当区域在动态仲裁的过程中从仲裁集中删除时,这些区域将无法再提供读取服务,直到重新添加到仲裁中为止。

有限过期一致性

对于具有两个或更多区域的单区域写入帐户,数据将从主要区域复制到所有次要(只读)区域。 对于具有两个或更多区域的多区域写入帐户,数据将从最初写入的区域复制到所有其他可写区域。 在这两种情况下,偶尔可能会有从一个区域到另一个区域的复制延迟(不常见)。

在有限过期一致性中,任何两个区域之间的数据延迟始终小于指定量。 数量可以是“K”个项版本(即“更新”)或“T”时间间隔,以先达到者为准。 换言之,如果选择有限过期,则可以通过两种方式配置任何区域中数据的最大“过期”值:

  • 项的版本数 (K)
  • 时间间隔 (T) 读取操作可以滞后于写入操作

有限过期主要有利于具有两个或更多区域的单区域写入帐户。 如果某个区域中的数据延迟(按物理分区确定)超过了配置的过期值,将会限制该分区的写入,直到过期值重新处于配置的上限范围内。

对于单区域帐户,有限过期提供与会话和最终一致性相同的写入一致性保证。 使用有限过期,数据会复制到单区域中的本地多数副本(包含四个副本的副本集中的三个副本)。

重要

使用有限过期一致性时,过期检查仅在区域之间进行,而不是在某个区域内进行。 在给定区域内,无论一致性级别如何,数据将始终复制到本地多数副本(含四个副本的副本集中的三个副本)。

使用有限过期时的读取将通过从该区域内的两个可用副本进行读取,返回该区域内的最新可用数据。 由于区域内的写入始终复制到本地多数副本(四个副本中的三个),因此,查询两个副本将返回该区域中可用的最新数据。

重要

使用有限过期一致性,针对非主要区域发出的读取可能不一定返回多区域最新版数据,但保证返回该区域中数据的最新版本(将在多区域最大有限过期内)。

有限过期最适合使用某个单区域写入帐户(具有两个或两个以上区域)的多区域分布式应用程序,其中需要跨区域的准强一致性。 对于具有两个或更多区域的多区域写入帐户,应用程序服务器应将读取和写入定向到托管应用程序服务器的同一区域。 多写入帐户中的有限过期是一种反模式。 该级别需要依赖于区域之间的复制延迟,如果数据是从写入数据的同一区域中读取的,这就无关紧要。

下图以乐谱形式演示了有限过期一致性。 将数据写入“中国北部 2”区域后,“中国东部 2”和“澳大利亚东部”区域将会根据所配置的最大滞后时间或最大操作数目读取写入的值:

动画使用音符演示最终在预定义的时间或版本延迟内同步的有限过期一致性级别。

会话一致性

在会话一致性的单个客户端会话中,可以保证读取遵守“读取你的写入内容”和“读取后写入”。 这保证采用单个“写入器”会话,或者多个写入器共享会话令牌。

与所有弱于“强”的一致性级别一样,写入内容将复制到本地区域中的至少三个副本(在包含四个副本的集中),并异步复制到所有其他区域。

每次执行写入操作后,客户端将从服务器接收更新的会话令牌。 客户端缓存令牌,并将其发送到服务器,以便在指定区域进行读取操作。 如果对其发出读取操作的副本包含指定的令牌(或时间更新的令牌)的数据,则返回请求的数据。 如果副本不包含该会话的数据,客户端将对该区域中的另一个副本重试请求。 如果需要,客户端将对其他可用区域重试读取,直到检索到指定的会话令牌的数据。

重要

在会话一致性中,客户端对会话令牌的使用保证永远不会读取对应于旧会话的数据。 但是,如果客户端使用的是较旧会话令牌并且在更近的时间对数据库进行了更新,则尽管使用的是较旧的会话令牌,但仍会返回较新版本的数据。 会话令牌用作最低版本屏障,而不是用作要从数据库中检索的数据的特定版本(可能是历史版本)。

Azure Cosmos DB 中的会话令牌是分区绑定的,这意味着它们只与一个分区相关联。 为了确保可以读取写入,请使用上次为相关项生成的会话令牌。

如果客户端未启动对物理分区的写入,它就不会在其缓存中包含会话令牌,并且对该物理分区的读取会表现为具有最终一致性的读取。 同样,如果重新创建了客户端,也会重新创建其会话令牌的缓存。 在此处,读取操作也将遵循与最终一致性相同的行为,直到后续的写入操作重新生成客户端的会话令牌缓存。

重要

如果将会话令牌从一个客户端实例传递到另一个实例,则不应修改令牌的内容。

“会话一致性”是最广泛用于单个区域以及多区域分布式应用程序的一致性级别。 它提供与最终一致性相当的写入延迟、可用性和读取吞吐量。 会话一致性还提供一致性保证,从而满足用于在用户上下文中操作的应用程序的需求。 下图以乐谱形式演示了会话一致性。 “中国北部 2 写入器”和“中国东部 2 读取器”正在使用同一个会话(会话 A),因此它们会同时读取相同的数据。 而“澳大利亚东部”区域正在使用“会话 B”,因此,它会稍后才会接收到数据,但接收顺序与写入顺序相同。

动画使用音符演示在单个客户端会话中同步的会话一致性级别。

一致前缀一致性

与所有弱于非常一致性的级别一样,写入内容将复制到本地区域中的至少三个副本(在包含四个副本的集中),并异步复制到所有其他区域。

在一致的前缀中,作为单个文档写入进行的更新将实现最终一致性。

对于在事务中作为批处理进行的更新,返回时将与提交它们的事务一致。 多文档事务中的写入操作始终一起可见。

假设在事务 T1 和 T2 中,以事务方式依次对文档 Doc1 和文档 Doc2 执行两个写入操作(全有或全无操作)。 当客户端在任何副本中执行读取操作时,用户将看到“Doc1 v1 和 Doc2 v1”或“Doc1 v2 和 Doc2 v2”或看不到任何一个文档(如果副本延迟),但在同一个读取或查询操作中绝不会看到“Doc1 v1 和 Doc2 v2”或“Doc1 v2 和 Doc2 v1”。

下图以乐谱形式演示了一致前缀一致性。 在所有区域中,读取永远不会看到事务写入批的无序写入:

动画使用音符演示最终同步但却视为未失序事务的一致性前缀级别。

最终一致性

与所有弱于非常一致性的级别一样,写入内容将复制到本地区域中的至少三个副本(在包含四个副本的集中),并异步复制到所有其他区域。

在最终一致性中,客户端对指定区域内四个副本中的任何一个发出读取请求。 此副本可能会滞后,并可能返回过时的数据或不返回数据。

最终一致性是最弱的一致性形式,因为客户端可能会读取比之前读取的值还要旧的值。 最终一致性非常适合于应用程序不需要任何顺序保证的情况。 示例包括推文、点赞或无回复评论的计数。 下图以乐谱形式演示了最终一致性。

动画使用音符演示最终同步但不在特定范围内的最终一致性级别。

一致性保证的实践

在实践中,你可能经常会获得更强的一致性保证。 读取操作的一致性保证对应于所请求的数据库状态的新旧程度和顺序。 读取一致性与写入/更新操作的排序和传播有关。

如果未在数据库上执行任何写入操作,具有“最终”、“会话”或“一致前缀”一致性级别的读取操作可能产生与具有非常一致性级别的读取操作相同的结果 。

如果帐户配置了除非常一致性以外的一致性级别,则可以弄清楚客户端获取工作负载的非常一致读取的概率。 可以通过查看 “概率有限 过期(PBS) ” 指标来确定此概率。 此指标在 Azure 门户中公开,若要了解详细信息,请参阅监视概率有限过期性 (PBS) 指标

概率有限过期显示了最终一致性的最终程度。 通过此指标可深入了解在 Azure Cosmos DB 帐户中获得比目前配置的一致性级别更强的一致性的频率。 换句话说,可看到获得写入和读取区域组合的一致读取的概率(以毫秒计量)。

一致性级别和延迟

所有一致性级别的读取延迟始终保证在第 99 百分位小于 10 毫秒。 平均(在第 50 百分位)读取延迟通常不超过 4 毫秒。

所有一致性级别的写入延迟始终保证在第 99 百分位小于 10 毫秒。 平均(在第 50 百分位)写入延迟通常不超过 5 毫秒。 跨多个区域且使用非常一致性配置的 Azure Cosmos DB 帐户不在此保障内。

写入延迟和非常一致性

对于配置了与多个区域具有非常一致性的 Azure Cosmos DB 帐户,写入延迟等于任意两个最远区域区域之间的往返时间 (RTT) 的两倍,加上第 99 个百分位数处的 10 毫秒。 区域之间的高网络 RTT 将转换为 Azure Cosmos DB 请求的更高延迟,因为只有在确保已将操作提交到帐户中的所有区域之后,非常一致性才会完成该操作。

确切的 RTT 延迟取决于光速距离和 Azure 网络拓扑。 Azure 网络不为任何两个 Azure 区域之间的 RTT 提供任何延迟 SLA,但它会发布 Azure 网络往返延迟统计信息。 对于 Azure Cosmos DB 帐户,将在 Azure 门户中显示复制延迟。 可以通过转到“指标”部分,然后选择“一致性”选项来使用 Azure 门户。 使用 Azure 门户可以监视与你的 Azure Cosmos DB 帐户关联的各个区域之间的复制延迟。

重要

由于写入延迟大,默认情况下会阻止区域跨越 5000 英里(8000 公里)以上的帐户的非常一致性。 若要启用此功能,请联系支持人员。

一致性级别和吞吐量

  • 对于非常一致性和有限过期一致性,将针对一个四副本集中的两个副本(少数仲裁)进行读取,以提供一致性保证。 会话一致性、一致前缀一致性和最终一致性执行单副本读取。 结果是,在请求单位数量相同的情况下,非常一致性和有限过期一致性的读取吞吐量是其他一致性级别的一半。

  • 对于给定类型的写入操作(例如插入、替换、更新插入和删除),所有一致性级别为请求单元提供的写入吞吐量是相同的。 为了实现非常一致性,需要在每个区域(全局多数)提交更改,而对于其他所有一致性级别,则使用本地多数(含四个副本的副本集中的三个副本)。

一致性级别 仲裁读取 仲裁写入
非常 本地少数 全局多数
有限过期 本地少数 本地多数
会话 单个副本(使用会话令牌) 本地多数
一致前缀 单个副本 本地多数
最终 单个副本 本地多数

注意

就读取成本 (RU) 而言,本地少数读取是较弱一致性级别的两倍,因为为了使强一致性和有界一致性级别保持一致,读取是从两个副本中完成的。

一致性级别和数据持续性

在多区域分布式数据库环境中,当发生区域范围的服务中断时,一致性级别与数据持续性之间存在直接关系。 在制定业务连续性计划时,需要了解从中断事件恢复时,应用程序可忍受最近数据更新丢失的最长期限。 可以承受更新丢失的时限称为恢复点目标 (RPO)。

此表定义了当发生区域范围的服务中断时,一致性模型与数据持续性之间的关系。

区域 复制模式 一致性级别 RPO
1 单个或多个写入区域 任何一致性级别 < 240 分钟
>1 单个写入区域 会话、一致的前缀或最终 < 15 分钟
>1 单个写入区域 有限过期 K & T
>1 单个写入区域 非常 0
>1 多个写入区域 会话、一致的前缀或最终 < 15 分钟
>1 多个写入区域 有限过期 K & T

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

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

对于单区域帐户,K 和 T 的最小值为 10 个写入操作或 5 秒 。 对于多区域帐户,K 和 T 的最小值为 100,000 个写入操作或 300 秒 。 该值定义了使用有限过期时数据的最小 RPO。

非常一致性和多个写入区域

具有多个写入区域的 Azure Cosmos DB 帐户不能配置为实施非常一致性,因为分布式系统不可能在提供为零的 RPO 的同时提供为零的 RTO。 另外,将非常一致性与多个写入区域配合使用时,没有写入延迟优势,因为对任何区域的任何写入必须在复制后提交到帐户中的所有已配置区域。 这种情况会导致写入延迟与单写入区域帐户相同。

进一步阅读

若要详细了解一致性的概念,请阅读以下文章:

后续步骤

要详细了解 Azure Cosmos DB 中的一致性级别,请阅读以下文章: