你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure Cosmos DB 集成缓存 - 概述

适用范围: NoSQL

Azure Cosmos DB 集成缓存是一种内存中缓存,可帮助你在请求量增长时确保成本可管理和低延迟。 集成缓存易于设置,无需花费时间编写用于缓存失效或管理后端基础结构的自定义代码。 集成缓存在 Azure Cosmos DB 帐户中将使用专用网关。 预配专用网关时,可以根据工作负载所需的核心数和内存数来选择节点数和节点大小。 每个专用网关节点都具有独立于其他节点的集成缓存。

集成缓存在专用网关上自动配置。 集成缓存包括两个部分:

  • 用于点读取的项缓存
  • 用于查询的查询缓存

集成缓存是一种读写缓存,使用最近最少使用的 (LRU) 逐出策略。 项缓存和查询缓存在集成缓存中共享相同的容量,并且 LRU 逐出策略对两者都适用。 从缓存中逐出数据时,将严格按照其最近最少使用的时间进行,而不考虑是点读取还是查询。 每个节点中缓存的数据取决于最近通过该特定节点写入或读取的数据。 如果在一个节点上缓存了某个项或查询,不一定会在其他节点上缓存该项或查询。

注意

你对集成缓存有何反馈? 我们想听一听! 欢迎直接与 Azure Cosmos DB 工程团队分享反馈:cosmoscachefeedback@microsoft.com

受益于集成缓存的工作负载

集成缓存的主要目标是降低读取密集型工作负载的成本。 虽然低延迟的优点也有用,但这不是集成缓存的主要优势,因为 Azure Cosmos DB 已经足够块而无需缓存。

命中集成缓存的点读取和查询的 RU 费用为 0。 与从后端数据库读取比较,缓存命中的每个操作成本要低得多。

符合以下特征的工作负载应评估集成缓存是否有助于降低成本:

  • 读取密集型工作负荷
  • 针对大型项的多次重复点读取
  • 多次重复高 RU 查询
  • 用于读取的热分区键

影响预期节省的最大因素是读取重复的程度。 如果工作负载在短时间内持续执行相同的点读取或查询,则它非常适合使用集成缓存。 使用集成缓存进行重复读取时,仅在首次读取时使用 RU。 通过同一专用网关节点(在 MaxIntegratedCacheStaleness 窗口中,并且尚未逐出数据)路由的后续读取不会使用吞吐量。

某些工作负载不应考虑使用集成缓存,包括:

  • 写入密集型工作负荷
  • 极少重复的点读取或查询
  • 读取更改源的工作负载

项缓存

项缓存用于进行点读取(基于项 ID 和分区键进行键/值查找)。

填充项缓存

  • 新的写入、更新和删除操作会自动填充到路由请求的节点的项缓存中
  • 来自点读取请求(其中项不在路由该请求的节点缓存中,即缓存未命中)的项将添加到项缓存中
  • 属于事务批处理或处于批量模式的请求将不会填充项缓存

项缓存失效和逐出

由于每个节点都有一个独立的缓存,因此一个节点中的项可能无效或被逐出,但在其他节点中则不会如此。 给定节点缓存中的项将根据以下条件失效并逐出:

  • 项更新或删除
  • 最近最早使用的 (LRU)
  • 缓存保留时间(即 MaxIntegratedCacheStaleness

查询缓存

查询缓存的用途是缓存查询。 查询缓存可将查询转换为键/值查找,其中键是查询文本,值则是查询结果。 集成缓存没有查询引擎,只存储每个查询的键/值查找。 查询结果将存储为一组,并且缓存不会跟踪各个项。 如果给定项出现在多个查询的结果集中,则可以将其多次存储在查询缓存中。 对基础项的更新不会反映在查询结果中,除非达到了查询的最大集成缓存过期时间,并且查询是从后端数据库提供的。

填充查询缓存

  • 如果缓存在其路由经过的节点上没有该查询的结果(缓存未命中),则会将查询发送到后端。 运行查询后,缓存将存储该查询的结果
  • 具有相同形状但参数不同,或请求选项会影响结果(例如,最大项计数)的查询将存储为自己的键/值对

查询缓存逐出

查询缓存逐出基于路由请求通过的节点。 查询可能在一个节点上逐出或刷新,但在其他节点上则不会。

  • 最近最早使用的 (LRU)
  • 缓存保留时间(即 MaxIntegratedCacheStaleness

使用查询缓存

使用查询缓存时不需要特殊代码,即使查询具有多个结果页也是如此。 无论查询是命中集成缓存还是在后端查询引擎上执行,查询分页的最佳做法和代码都是相同的。

查询缓存会自动缓存查询延续令牌(如果适用)。 如果查询包含多个结果页,则存储在集成缓存中的任何页的 RU 费用为 0。 如果后续查询结果页面要求后端执行,它们将具有上一页中的延续令牌,因此可以避免重复以前的工作。

重要

不同专用网关节点内的集成缓存实例具有相互独立的缓存。 如果数据缓存在一个节点中,则不一定会缓存在其他节点中。 不保证将同一查询的多个页面路由到同一专用网关节点。

集成缓存一致性

集成缓存仅支持具有会话和最终一致性的读取请求。 如果读取具有一致的前缀、有限过期或强一致性,则将绕过集成缓存并由后端提供。

若要为所有读取操作配置会话或最终一致性,最简单的方法是在帐户级别设置最终一致性。 但是,如果只希望某些读取具有特定一致性,也可在请求级别配置一致性。

注意

具有其他一致性的写入请求仍会填充缓存,但为了从缓存中进行读取,请求必须具有会话或最终一致性。

会话一致性

会话一致性是使用最广泛的一致性级别,可用于单个区域和全球分布的 Azure Cosmos DB 帐户。 借助会话一致性,单客户端会话可以读取自己的写入内容。 任何具有会话一致性且没有匹配会话令牌的读取都将产生 RU 费用。 这包括启动或重启客户端应用程序时对给定项或查询的第一个请求,除非显式传递有效的会话令牌。 在使用集成缓存时,执行写入的会话外部客户端将会看到最终一致性。

MaxIntegratedCacheStaleness

MaxIntegratedCacheStaleness 是缓存点读取和查询的最大可接受过期时间,而与所选一致性无关。 MaxIntegratedCacheStaleness 可在请求级别进行配置。 例如,如果将 MaxIntegratedCacheStaleness 设置为 2 小时,则仅当数据的有效期小于 2 小时的时候,请求才会返回缓存数据。 若要增加利用集成缓存进行重复读取的可能性,应将 MaxIntegratedCacheStaleness 设置为业务要求允许的最高值。

如果在最终填充缓存的请求上进行配置,则 MaxIntegratedCacheStaleness 将不会影响该请求的缓存时间。 MaxIntegratedCacheStaleness 在尝试读取缓存数据时强制执行一致性。 由于不存在全局 TTL 或缓存保留设置,因此,只有在集成缓存已满或新读取运行的 MaxIntegratedCacheStaleness 低于当前缓存条目的年限时,才会从缓存中逐出数据。

这是对大多数缓存工作方式的改进,并允许以下其他自定义项:

  • 可以针对每个点读取或查询设置不同的过期时间要求
  • 即使运行相同的点读取或查询,不同的客户端也可以配置不同的 MaxIntegratedCacheStaleness
  • 如果要修改缓存数据的读取一致性,则更改 MaxIntegratedCacheStaleness 将会立即影响读取一致性

注意

MaxIntegratedCacheStaleness 最小值为 0,最大值为 10 年。 如果未显式配置,则 MaxIntegratedCacheStaleness 默认值为 5 分钟。

为了更好地了解 MaxIntegratedCacheStaleness 参数,请考虑以下示例:

时间 请求 响应
t = 0 秒 运行 MaxIntegratedCacheStaleness = 30 秒的查询 A 从后端数据库返回结果(正常 RU 费用)并填充缓存
t = 0 秒 运行 MaxIntegratedCacheStaleness = 60 秒的查询 B 从后端数据库返回结果(正常 RU 费用)并填充缓存
t = 20 秒 运行 MaxIntegratedCacheStaleness = 30 秒的查询 A 从集成缓存返回结果(0 RU 费用)
t = 20 秒 运行 MaxIntegratedCacheStaleness = 60 秒的查询 B 从集成缓存返回结果(0 RU 费用)
t = 40 秒 运行 MaxIntegratedCacheStaleness = 30 秒的查询 A 从后端数据库返回结果(正常 RU 费用)并刷新缓存
t = 40 秒 运行 MaxIntegratedCacheStaleness = 60 秒的查询 B 从集成缓存返回结果(0 RU 费用)
t = 50 秒 运行 MaxIntegratedCacheStaleness = 20 秒的查询 B 从后端数据库返回结果(正常 RU 费用)并刷新缓存

了解如何配置 MaxIntegratedCacheStaleness

绕过集成缓存(预览版)

集成缓存的存储容量有限,具体由预配的专用网关 SKU 决定。 默认情况下,客户端中使用专用网关连接字符串配置的所有请求都经过集成缓存并占用缓存空间。 可以使用“绕过集成缓存”请求选项(目前为预览版)控制缓存的项和查询。 对于不经常重复的项写入或读取请求,此请求选项很有用。 绕过不经常访问的项的集成缓存可以节省更多重复项的缓存空间,从而提高 RU 节省潜力并减少逐出。 绕过缓存的请求仍通过专用网关来路由。 这些请求均由后端和成本 RU 处理。

了解如何绕过集成缓存

指标

监视集成缓存的某些关键指标会有帮助。 这些指标包括:

  • DedicatedGatewayCPUUsage - 跨所有专用网关节点的数据使用 Avg、Max 或 Min 聚合类型的 CPU 使用情况。
  • DedicatedGatewayAverageCPUUsage -(已弃用)跨所有专用网关节点的平均 CPU 使用率。
  • DedicatedGatewayMaximumCPUUsage -(已弃用)跨所有专用网关节点的最大 CPU 使用率。
  • DedicatedGatewayMemoryUsage - 跨所有专用网关节点的数据使用 Avg、Max 或 Min 聚合类型的内存使用情况。
  • DedicatedGatewayAverageMemoryUsage -(已弃用)跨所有专用网关节点的平均内存使用率。
  • DedicatedGatewayRequests - 跨所有专用网关节点的专用网关请求总数。
  • IntegratedCacheEvictedEntriesSize - 由于 LRU 而从所有专用网关节点的集成缓存中逐出的平均数据量。 此值不包括因超过 MaxIntegratedCacheStaleness 时间而过期的数据。
  • IntegratedCacheItemExpirationCount - 由于跨所有专用网关节点的缓存点读取超过 MaxIntegratedCacheStaleness 时间而从集成缓存中逐出的平均项数。
  • IntegratedCacheQueryExpirationCount - 由于跨所有专用网关节点的缓存查询超过 MaxIntegratedCacheStaleness 时间而从集成缓存中逐出的平均查询数。
  • IntegratedCacheItemHitRate - 使用集成缓存的点读取比例(在通过具有会话一致性或最终一致性的专用网关路由的所有点读取中的占比)。 此值是所有专用网关节点的集成缓存实例的平均值。
  • IntegratedCacheQueryHitRate - 使用集成缓存的查询比例(在通过具有会话一致性或最终一致性的专用网关路由的所有查询中的占比)。 此值是所有专用网关节点的集成缓存实例的平均值。

默认情况下,所有现有指标将在 Azure 门户的“指标”中提供(不是“指标”经典):

Screenshot of the Azure portal that shows the location of integrated cache metrics.

指标是所有专用网关节点的平均值、最大值或总和。 例如,如果预配包含五个节点的专用网关群集,则指标反映所有五个节点的聚合值。 无法确定每个单独节点的指标值。

排查常见问题

以下示例显示了如何调试一些常见场景:

我无法判断应用程序是否正在使用专用网关

检查 DedicatedGatewayRequests。 此指标包括所有使用专用网关的请求,而不考虑请求是否命中集成缓存。 如果应用程序使用标准网关或原始连接字符串的直接模式,则不会出现错误消息,但 DedicatedGatewayRequests 将为 0。 如果应用程序对专用网关连接字符串使用直接模式,则仍可能会看到少许 DedicatedGatewayRequests

我无法判断请求是否命中集成缓存

检查 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate。 如果这两个值都为零,则请求不会命中集成缓存。 检查是否正在使用专用网关连接字符串、是否通过网关模式进行连接,以及是否正在使用会话或最终一致性

我想要了解专用网关是否过小

检查 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate。 如果值较高(例如高于 0.7-0.8),则很明显地表示专用网关足够大。

如果 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate 较低,请查看 IntegratedCacheEvictedEntriesSize。 如果 IntegratedCacheEvictedEntriesSize 较高,可能表示更大的专用网关大小会更有用。 可通过增加专用网关大小并比较新的 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate 进行试验。 如果较大的专用网关无法提高 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate,那么读取操作可能不足以通过重复自身来使集成缓存具有影响力。

我想要了解专用网关是否过大

与测量专用网关是否过小相比,更难测量专用网关是否过大。 通常应从较少的量开始,然后慢慢增加专用网关大小,直到 IntegratedCacheItemHitRateIntegratedCacheQueryHitRate 停止增加。 在某些情况下,两个缓存命中指标中只有一个很重要,而不是两个都重要。 例如,如果工作负载主要是查询,而不是点读取,则 IntegratedCacheQueryHitRateIntegratedCacheItemHitRate 重要得多。

如果大多数数据是因为超过 MaxIntegratedCacheStaleness(而不是 LRU)而从缓存中逐出,则缓存可能大于所需大小。 如果 IntegratedCacheItemExpirationCountIntegratedCacheQueryExpirationCount 的组合几乎与 IntegratedCacheEvictedEntriesSize 一样大,可尝试使用较小的专用网关大小并比较性能。

我想要了解是否需要添加更多专用网关节点

在某些情况下,如果延迟异常高,可能需要更多专用网关节点,而不是更大的节点。 检查 DedicatedGatewayCPUUsageDedicatedGatewayMemoryUsage,以确定添加更多专用网关节点是否可以减少延迟。 请记住,由于集成缓存的所有实例彼此独立,因此添加更多专用网关节点不会减少 IntegratedCacheEvictedEntriesSize。 不过,添加更多节点可以提高专用网关群集可以处理的请求量。

后续步骤