本页面提供了有关以最优方式使用 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 资源。每个分片最多可以有 5 个副本。
此外,我们建议您管理节点 CPU 使用情况,以便节点有足够的 CPU 开销来处理因意外的可用区中断而导致的容量损失所带来的额外流量。您应使用 Main Thread CPU Seconds /instance/cpu/maximum_utilization
指标监控主线程和副本的 CPU 使用情况。
根据您为每个节点配置的副本数,我们建议采用以下 /instance/cpu/maximum_utilization
CPU 使用率目标值:
- 对于每个节点有一个副本的实例,主实例的目标
/instance/cpu/maximum_utilization
值为 0.5 秒,副本的目标/instance/cpu/maximum_utilization
值为 0.5 秒。 - 对于每个节点有两个或更多副本的实例,请将主实例的
/instance/cpu/maximum_utilization
目标值设为 0.9 秒,并将每个副本的/instance/cpu/maximum_utilization
目标值设为 0.5 秒。
如果相应指标的值超过了这些建议值,我们建议您增加实例中的分片数量。如果您的实例的副本数少于 5 个,您还可以扩容副本数,最多可扩容到 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 服务器发出 SLOTS
、NODES
或 CLUSTER 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 快照用于工作负载的好处。
添加副本
添加副本需要 RDB 快照。如需详细了解 RDB 快照,请参阅内存管理。
如果您的实例不使用副本,请选择单可用区实例
在配置没有副本的实例时,我们建议采用单可用区架构,以提高可靠性。原因如下:
尽量减少中断的影响
可用区级服务中断不太可能影响您的实例。通过将所有节点放置在单个可用区内,可用区中断影响服务器的几率从 100% 降至 33%。这是因为,实例所在的可用区发生故障的几率为 33%,而位于不可用可用区中的节点受到影响的几率为 100%。
快速恢复
如果发生可用区级服务中断,恢复流程会更加顺畅。您可以快速在正常运行的可用区中预配新实例,并重定向应用,以尽可能减少中断。
启用传输层安全协议 (TLS)
本部分介绍了使用传输层安全协议 (TLS) 的安全优势和性能影响,并提供了有关启用 TLS 的建议。
安全优势
通过使用 TLS,您可以获得以下安全优势:
- Identity and Access Management (IAM) 身份验证:TLS 使用此类身份验证来防范服务器欺骗攻击,例如中间人攻击。
- 传输加密:Google Cloud的内置加密功能可在基础架构层面保护 Google 网络内的流量。不过,这需要信任 Google 的主机和网络堆栈。虽然此加密是透明的,并且默认处于启用状态,但它不是端到端加密。另一方面,TLS 在应用层使用传输中加密。此端到端加密功能可让您更好地控制加密密钥和流程。
- 身份验证令牌保护:如果您使用 IAM 身份验证,那么启用 TLS 可最大限度地降低身份验证令牌暴露和泄露的风险。
性能影响
TLS 会通过以下方式影响性能:
建立连接:已建立 TLS 会话的客户端和服务器可以恢复该会话,而无需重复执行在客户端和服务器之间建立连接的资源密集型流程。通过启用 TLS 恢复,您可以减少客户端与服务器之间建立连接的开销。
如果您不建立 TLS 恢复,那么建立连接会消耗大量资源。对于新连接和现有连接,客户端与服务器之间的连接过多可能会导致连接超时。这可能会导致滚雪球效应,因为 Memorystore for Valkey 会尝试重新建立超时连接,从而增加其用于建立连接的资源。
加密和解密数据:数据加密和解密涉及 CPU 密集型操作,会影响客户端和服务器。这会降低实例的容量,并增加实例的延迟时间。
建议
在考虑是否启用 TLS 时,我们建议您在权衡 TLS 的优缺点后评估您的安全政策。如果您选择启用 TLS,请注意以下事项:
- 启用 TLS 恢复可减少建立连接的开销。客户端与服务器之间的连接仅在初始连接时需要。不过,如果客户的实例大小突然扩大,可能会因每个新客户端主机的初始完整握手而导致短暂中断。
- 虽然某些客户端库可能不提供用于启用 TLS 的内置控件,但您可以使用自定义代码将此功能集成到实例中。