关于读取副本

Memorystore for Redis 的标准层级提供了通过读取副本调节应用的读取查询的功能。本页面假定您熟悉不同的 Memorystore Redis 层级功能

读取副本允许您通过查询副本来扩缩读取工作负载。读取端点使应用能够更轻松地跨副本分布查询。如需了解详情,请参阅通过读取端点扩缩读取

如需了解如何管理具有读取副本的 Redis 实例,请参阅管理读取副本

读取副本的使用场景

会话存储、排行榜、商品推荐引擎和其他使用场景要求实例具备高可用性。在这些使用场景中,读取远多于写入,并且这些使用场景通常能够容忍一些过时读取。在这些情况下,利用读取副本提高实例的可用性和可伸缩性是十分明智的选择。

读取副本行为

  • 默认情况下,标准层级实例上不启用读取副本。
  • 在实例上启用读取副本后,便无法再为该实例停用读取副本。
  • 标准层级实例可以有 1 到 5 个读取副本。
  • 读取端点提供跨副本节点分发查询的单一端点。
  • 读取副本使用 Redis 异步复制进行维护。

注意事项和限制

  • 只有节点数大于等于 5 GB 的实例大小才支持读取副本。
  • 只能在使用 Redis 5.0 或更高版本的实例上启用读取副本。
  • 如果您为节点预配指定一个可用区和一个备用可用区,Memorystore 会将这些可用区用于实例中的第一个和第二个节点。之后,Memorystore 会为该实例预配的所有剩余节点选择可用区。
  • 您必须为实例预配等于或大于 /28 的 CIDR IP 地址范围。更大的范围(例如 /27/26)是有效的。此功能不支持更小的范围(例如 /29)。

架构

启用读取副本时,您可以指定实例中所需的副本数量。Memorystore 会自动在一个区域内可用的可用区中分布主节点和读取副本节点。

每个实例都有一个主端点和一个读取端点。主端点始终将流量定向到主节点,而读取端点会自动在可用副本之间对读取查询进行负载均衡。

Memorystore for Redis 健康监控服务会监控实例,并负责检测主节点的任何故障。它会选择副本作为新的主节点,并启动到新的主节点的自动故障切换。

具有读取副本的实例的故障切换

当主节点发生故障时,Memorystore 健康监控服务会启动故障切换,以提供新的主节点用于读写查询。故障切换通常在 30 秒内完成。

发生故障切换时,主端点会自动将流量重定向到新的主节点,但在故障切换期间,主端点的所有客户端连接都会断开。一旦新的主节点上线,具有连接重试逻辑的应用将自动重新连接。在故障切换期间,读取端点的某些客户端连接也会从在故障切换期间提升为主节点的读取副本断开。在此期间,与其余副本的连接将继续存在。在重试时,这些连接会重定向到新副本。

发生故障切换时,由于复制的异步特性,副本的复制延迟可能会有所不同。但是,故障切换过程会尽最大努力故障切换到具有最小延迟的副本。这有助于最大限度地减少故障切换期间的数据丢失和读取吞吐量下降。新提升的主节点可以与之前的主节点位于同一可用区,也可以位于不同可用区。如果某个副本与之前的主节点位于同一可用区并具有最小的延迟,则该副本会被选为新的主节点。否则,其他可用区中的副本可能成为新的主节点。

由于复制是异步进行的,因此故障切换期间始终存在读取过时数据的可能性。此外,在提升新的主节点时,对实例的一些写入可能会丢失。应用应该能够应对此行为。

Redis 会尽力避免其他副本在故障切换期间进行完全同步,但在极少数情况下仍可能发生。完全同步可能需要几分钟到一个小时,具体取决于写入速率和复制的数据集的大小。在此期间,进行完全同步的副本无法用于读取。同步完成后,副本才可用于读取。

读取副本的故障模式

具有读取副本的实例可能会遇到影响应用的各种故障和不健康情况。实例的行为取决于它是有一个副本,还是两个或多个副本。本部分简要介绍了一些常见的故障模式以及实例在这些情况下的行为。

副本不可用

  • 当副本因任何原因发生故障时,会被标记为不可用,并且副本的所有连接都会在特定超时后终止。副本恢复后,新连接会路由到恢复的副本。副本的恢复时间因故障模式而异。

  • 如果 Compute Engine 缺货或可用区发生故障,则副本只有在故障解除后才会恢复。

可用区故障

  • 如果主节点所在的可用区发生故障,则主节点会自动故障切换到另一个可用区中的副本。如果实例只有一个副本,则读取端点在可用区服务中断期间不可用。如果实例有多个副本,则受影响可用区之外的副本可用于读取。

  • 如果一个或多个副本所在的可用区发生故障,则这些副本在可用区故障期间不可用。如果有两个可用区发生故障,并且有两个或多个副本,则剩余可用区中具有最小延迟的副本将被提升为主节点。未受影响的可用区中的任何剩余副本都可供读取。

网络分区

网络分区是这样一种场景,即节点保持运行但无法访问所有客户端、可用区或对等节点。Memorystore 使用基于仲裁的系统来防止孤立节点处理写入请求。发生网络分区时,如果少数分区中有主节点,则主节点会自我降级。多数分区(如果有)中如果没有主节点,则会选择一个新的主节点。孤立副本会继续处理读取请求。但是,如果它们无法与主节点同步,则可能会过时。

要确定链路是否中断,请监控 master_link_down_since_secondsoffset_diff 指标以识别孤立节点。

缺货

有时,Memorystore 无法在一个可用区中获得需要的 Compute Engine 资源,这将导致缺货。如果您尝试在一个发生缺货的区域中预配实例,创建实例的操作将失败。

完全同步

当副本远远滞后于主节点时,会触发完全同步,将主节点的整个快照复制到副本中。根据具体情况,此操作可能需要几分钟到一小时的时间。完全同步不会导致实例故障,但在此期间,进行完全同步的副本无法用于读取,主节点会出现更高的 CPU 和内存利用率。

主端点返回 READONLY

您对包含读取副本的 Memorystore for Redis 实例的主端点执行写入操作时,可能会意外收到 -READONLY You can't write against a read only replica. 错误。我们建议您关闭与实例的连接,然后重新建立连接。在大多数情况下,重启客户端应用可以缓解这一问题。如果这些方法不可行或行为仍然存在,请与 Google Cloud 支持团队联系

通过读取端点扩缩读取

读取副本允许应用通过读取副本来扩缩其读取。应用可以通过读取端点连接到读取副本。

读取端点

读取端点是应用连接到的 IP 地址。它会将连接在实例中的副本之间进行负载均衡。与读取副本的连接可以发送读取查询,但不能发送写入查询。每个启用了读取副本的标准层级实例都有一个读取端点。如需了解如何查看实例的读取端点,请参阅查看实例的读取副本信息

读取端点的行为

  • 读取端点会自动在所有可用副本之间分布连接。连接不会定向到主节点。
  • 只要一个副本能够处理客户端流量,它就会被视为可用。这不包括副本进行主节点完全同步的时候。
  • 具有高复制延迟的副本会继续处理流量。具有高写入量的应用可以从处理大量写入查询的副本读取过时数据。
  • 如果副本节点成为主节点,则与该节点的连接会终止,并且新连接会重定向到新的副本节点。
  • 读取端点的各个连接会在其生命周期内定位相同的副本。无法保证来自同一客户端主机的不同连接能够定位同一副本节点。

读取一致性

读取副本使用原生 OSS Redis 异步复制进行维护。异步复制的性质导致副本可能滞后于主节点。具有持续稳定写入并且也从副本读取的应用应该能够容忍不一致的读取。

如果应用要求“读写”一致性,我们建议为写入和读取使用主端点。使用主端点可确保读取操作始终定向到主节点。即使在这种情况下,故障切换后仍然可能发生过时读取。

为主节点上的键设置 TTL 可确保无法从主节点或副本读取过期的键。这是因为 Redis 可确保无法从副本读取过期的键。

在现有实例上启用读取副本的行为

  • 在现有 Redis 实例上启用读取副本是一项排他操作,这意味着您无法在启用读取副本的同一操作中执行其他更新操作实例修改。

  • 要在现有 Redis 实例上启用读取副本,您需要分配另一个大小为 /28 的有效 IP 地址范围,而无论分配给 Memorystore for Redis 的现有 IP 地址范围的大小如何。

    • 为 Redis 实例启用读取副本时,必须提供额外的 IP 范围。您可以选择特定范围,也可以让 Memorystore 自动为您选择一个范围。
  • 启用读取副本时,实例的读写 IP 地址不会更改。读取端点 IP 地址位于为您的 Memorystore 实例分配的原始范围内,而不是您在启用读取副本时提供的其他范围。

  • 如需查找新的读取端点,请在启用读取副本的操作完成后,查看实例的读取副本信息

调节实例

您可以调节实例的读取副本数,还可以修改节点大小:

我们建议您在读写流量较低的时候扩缩实例,以最大限度地减少对应用的影响。

添加新副本会增加主节点的负载,因为新副本需要执行完全同步。添加节点时,现有连接不受影响,也不会转移。在新副本可用后,它将开始从端点接收连接并处理读取查询。移除副本会关闭路由到该副本的所有活动连接。应将客户端应用配置为自动重新连接到读取端点,以重新建立与其余副本的连接。

最佳实践

内存管理

Redis 不允许客户端写入超过实例的 maxmemory 限制。但是,碎片化、复制缓冲区和 EVAL 命令等开销可能会使内存利用率超出此限制。在这些情况下,Memorystore 会使写入失败,直到内存压力减小为止。如需了解详情,请参阅内存管理最佳实践

如果 Memorystore 由于导出或完全同步复制进行 BGSAVE 操作,并且发生 OOM 条件,则子进程会被终止。在这种情况下,BGSAVE 操作会失败,而 Redis 节点服务器仍然可用。

为了在所有情况下保证复制和快照创建,我们建议在重要操作(如导出、扩缩等)期间将内存利用率保持在 50% 以下。您可以手动触发导出故障切换来了解这些操作对性能的影响。

CPU 管理

Memorystore 提供每个节点的 CPU 利用率和连接计数的指标。我们建议您分配足够的开销,以便能够容忍失去单个可用区的情况。理想的目标可能会因副本数量和使用模式而异,但建议您先将副本的 CPU 使用率保持在 50% 以下。

如果客户端使用模式不均衡,或者故障切换操作导致连接分布不均衡,则单个节点可能会出现过高的利用率。在这种情况下,我们建议您定期关闭连接,以使 Memorystore 可以重新均衡分布连接。Memorystore 不会重新分布打开的连接。

连接均衡管理

每当节点的连接关闭时,客户端都必须重新连接,这通常通过在您选择的客户端库上启用自动重新连接实现。节点被重新引入时,现有连接不会重新路由,但新连接会路由到新节点。客户端可以定期终止连接,以确保连接在可用节点之间均衡分布。

复制延迟管理

副本有可能会延迟,特别是在写入速率很高的时候。在这种情况下,副本仍可用于读取,但来自副本的读取可能会过时,应用应该能够处理这种情况,或者应缓解写入速率过高的状况。

后续步骤