Memorystore for Valkey 最佳实践

本页面提供了有关以最优方式使用 Memorystore for Valkey 的指导。本页面还指出了需要避免的潜在问题。

内存管理最佳做法

本部分介绍了管理实例内存的策略,以便 Memorystore for Valkey 能够高效地为您的应用服务。

内存管理概念

  • 内存用量:实例使用的内存量。您有固定的内存容量。您可以使用指标来监控内存用量。

  • 逐出政策:Memorystore for Valkey 使用 volatile-lru 逐出政策。您可以使用 Valkey 命令(例如 EXPIRE 命令)为键设置逐出。

监控实例的内存用量

如需监控 Memorystore for Valkey 实例的内存用量,建议您查看 /instance/memory/maximum_utilization 指标。如果实例的内存使用率接近 80%,并且您预计数据使用量会增加,请扩大实例的规模,以便为新数据腾出空间。

如果实例的内存用量较高,请执行以下操作来提升性能:

如果您遇到问题,请与Google Cloud 客户服务联系。

在启用集群模式的情况下扩缩分片

当您扩缩实例中的分片数量时,建议您在写入负载较低的时段进行扩缩。在高使用率期间进行扩缩可能会因复制或 slot 迁移造成内存开销而导致实例的内存不足。

如果您的 Valkey 使用场景涉及键逐出,那么缩减实例规模可能会降低缓存命中率。不过,在这种情况下,您无需担心数据丢失,因为密钥逐出是预期行为。

对于不想丢失键的 Valkey 用例,您应仅缩减到仍有足够空间来存储数据的较小实例。新的目标分片数应至少为数据所用内存的 1.5 倍。换句话说,您应预配足够的分片,以容纳当前实例中 1.5 倍的数据量。您可以使用 /instance/memory/total_used_memory 指标来查看实例中存储的数据量。

CPU 使用率最佳实践

如果发生意外的可用区中断,则由于不可用可用区中的节点丢失了容量,您的实例的 CPU 资源会减少。我们建议使用高可用性实例。每个分片使用两个副本(而不是每个分片使用一个副本)可在中断期间提供额外的 CPU 资源。此外,我们建议您管理节点 CPU 使用情况,以便节点有足够的 CPU 开销来处理因可用区意外中断而导致的容量损失所带来的额外流量。您应使用 Main Thread CPU Seconds /instance/cpu/maximum_utilization 指标监控主副本和副本的 CPU 使用情况。

根据您为每个节点预配的副本数,我们建议采用以下 /instance/cpu/maximum_utilization CPU 使用率目标值:

  • 对于每个节点有 1 个副本的实例,您应将主数据库和副本的 /instance/cpu/maximum_utilization 值设为 0.5 秒。
  • 对于每个节点有 2 个副本的实例,您应将主实例的 /instance/cpu/maximum_utilization 值设为 0.9 秒,将副本的 /instance/cpu/maximum_utilization 值设为 0.5 秒。

如果该指标的值超过了这些建议值,我们建议您增加实例中的分片或副本数量。

资源密集型 Valkey 命令

我们强烈建议您避免使用占用大量资源的 Valkey 命令。使用这些命令可能会导致以下性能问题:

  • 延迟时间长和客户端超时
  • 因增加内存用量的命令而导致的内存压力
  • 节点复制和同步期间出现数据丢失,因为 Valkey 主线程被阻塞
  • 健康检查、可观测性和复制资源不足

下表列出了消耗大量资源的 Valkey 命令示例,并提供了资源效率更高的替代方案。

类别 资源密集型命令 资源节约型替代方案
针对整个键空间运行 KEYS SCAN
针对长度可变的密钥集运行 LRANGE 限制用于查询的范围的大小。
ZRANGE 限制用于查询的范围的大小。
HGETALL HSCAN
SMEMBERS SSCAN
阻止脚本运行 EVAL 确保脚本不会无限期运行。
EVALSHA 确保脚本不会无限期运行。
移除文件和链接 DELETE UNLINK
发布和订阅 PUBLISH SPUBLISH
SUBSCRIBE SSUBSCRIBE

Valkey 客户端最佳实践

避免 Valkey 上的连接过载

为缓解连接突然涌入所造成的影响,我们建议执行以下操作:

  • 确定最适合您的客户端连接池大小。每个客户端的合理初始大小为每个 Valkey 节点一个连接。然后,您可以进行基准比较,看看在不超出允许的最大连接数的情况下,增加连接数是否有助于提高性能。

  • 当客户端因服务器超时而与服务器断开连接时,请使用带抖动的指数退避算法进行重试。这有助于避免多个客户端同时使服务器过载。

对于已启用集群模式的实例

当应用连接到启用了集群模式的 Memorystore for Valkey 实例时,必须使用支持集群的 Valkey 客户端。如需查看集群感知型客户端和配置示例,请参阅客户端库代码示例。客户端必须维护从哈希槽到实例中相应节点的映射,以便将请求发送到正确的节点。这样可以避免重定向造成的性能开销。

客户端映射

在以下情况下,客户端必须获取完整的 slot 列表和映射的节点:

  • 当客户端初始化时,它必须填充初始 slot 到节点映射。

  • 当从服务器收到 MOVED 重定向时,例如在故障切换时,当之前的主节点服务的所有 slot 都被副本接管时,或者在重新分片时,当 slot 从源主节点移动到目标主节点时。

  • 当从服务器收到 CLUSTERDOWN 错误或与特定服务器的连接持续超时时。

  • 当从服务器收到 READONLY 错误时。当主节点降级为副本时,可能会发生这种情况。

  • 此外,客户端应定期刷新拓扑,以使客户端保持预热状态,从而应对任何更改,并了解可能不会导致服务器重定向/错误的更改,例如添加新的副本节点。请注意,任何过时的连接也应作为拓扑刷新的一部分关闭,以减少在命令运行时处理失败连接的需求。

客户端发现

客户端发现通常通过向 Valkey 服务器发出 SLOTSNODESCLUSTER SHARDS 命令来完成。我们建议使用 CLUSTER SHARDS 命令。CLUSTER SHARDS 通过提供更高效且可扩展的实例表示形式,取代了 SLOTS 命令(已弃用)。

客户端发现命令的响应大小可能会因实例大小和拓扑而异。节点较多的大型实例会生成较大的响应。因此,请务必确保执行节点拓扑发现的客户端数量不会无限增长。

这些节点拓扑刷新在 Valkey 服务器上开销很大,但对于应用可用性也很重要。因此,请务必确保每个客户端在任何给定时间只发出一个发现请求(并将结果缓存在内存中),并限制发出请求的客户端数量,以避免服务器过载。

例如,当客户端应用启动或与服务器断开连接并必须执行节点发现时,一个常见错误是,客户端应用在重试时未添加指数退避,而是发出了多次重新连接和发现请求。这可能会导致 Valkey 服务器长时间无响应,从而导致 CPU 利用率非常高。

使用发现端点进行节点发现

使用 Memorystore for Valkey 发现端点执行节点发现。发现端点具有高可用性,并且在实例中的所有节点之间实现负载平衡。此外,发现端点会尝试将节点发现请求路由到具有最新拓扑视图的节点。

对于已停用集群模式的实例

连接到已停用集群模式的实例时,您的应用必须连接到主端点才能写入实例并检索最新的写入内容。您的应用还可以连接到读取器端点,以便从副本读取数据并隔离来自主节点的流量。

持久性最佳实践

本部分介绍了有关持久性的最佳实践。

RDB 持久性

为了通过 RDB 快照备份实例获得最佳结果,您应遵循以下最佳实践:

内存管理

RDB 快照使用进程派生和“写入时复制”机制来拍摄节点数据的快照。根据对节点的写入模式,随着写入所触及的页面被复制,节点的已用内存会不断增长。在最糟糕的情况下,内存占用量可能是节点中数据大小的两倍。

为确保节点有足够的内存来完成快照,您应将 maxmemory 保持或设置为节点容量的 80%,以便预留 20% 的开销。如需了解详情,请参阅监控实例的内存用量。除了监控快照之外,此内存开销还有助于您管理工作负载,以便成功创建快照。

过时的快照

从过时快照恢复节点可能会导致应用出现性能问题,因为应用会尝试协调大量过时的密钥或对数据库的其他更改,例如架构更改。如果您担心从过时的快照中恢复,可以停用 RDB 持久性功能。重新启用持久性后,系统会在下一个预定的快照间隔时间拍摄快照。

RDB 快照对性能的影响

根据您的工作负载模式,RDB 快照可能会影响实例的性能,并会增加应用的延迟时间。如果您可以接受快照频率较低,则可以将 RDB 快照安排在低实例流量期间运行,以最大限度地降低 RDB 快照的性能影响。

例如,如果您的实例在凌晨 1 点到凌晨 4 点之间的流量较低,则可以将开始时间设置为凌晨 3 点,并将时间间隔设置为 24 小时。

如果您的系统具有恒定负载,并且需要频繁的快照,您应仔细评估性能影响,并权衡将 RDB 快照用于工作负载的好处。

如果您的实例不使用副本,请选择单可用区实例

在配置没有副本的实例时,我们建议采用单可用区架构,以提高可靠性。原因如下:

最大限度地降低中断的影响

可用区级服务中断不太可能影响您的实例。通过将所有节点放置在单个可用区内,可用区中断影响服务器的几率从 100% 降至 33%。这是因为实例所在可用区发生故障的几率为 33%,而位于不可用可用区中的节点受到影响的几率为 100%。

快速恢复

如果发生可用区级服务中断,恢复流程会更加顺畅。您可以快速在正常运行的可用区中预配新实例,并重定向应用,以尽可能减少中断。