在使用 ElastiCache for Redis 时,如何解决出现的高延迟问题?

2 分钟阅读
0

在使用 Amazon ElastiCache for Redis 时,如何解决出现的高延迟问题?

简短描述

以下是 ElastiCache for Redis 中延迟增加或超时问题的常见原因:

  • 缓慢的命令执行造成的延迟。
  • 高内存使用率导致的交换量增加。
  • 网络问题导致的延迟。
  • 客户端延迟问题。
  • ElastiCache 集群事件。

解决方案

缓慢的命令执行造成的延迟

Redis 主要是单线程执行。因此,当请求的服务速度较慢时,所有其他客户端都必须等待处理。这种等待会增加命令延迟。Redis 命令还具有使用 Big O 表示法定义的时间复杂性。

使用 ElastiCache 提供的 Amazon CloudWatch 指标来监控不同类别命令的平均延迟。值得注意的是,常见的 Redis 操作是以微秒延迟计算的。CloudWatch 指标每 1 分钟采样一次,其中延迟指标显示多个命令的汇总。因此,单个命令可能会导致意外结果,例如超时,而不会在指标图表中给出显著的变化。在这些情况下,使用 SLOWLOG 命令来帮助确定哪些命令需要更长的时间才能完成。连接到集群并在 redis-cli 中运行 slowlog get 128 命令来检索列表。有关更多信息,请参阅如何在 ElastiCache for Redis 缓存群集中开启 Redis 慢日志?

您可能还会看到 CloudWatch 中的 EngineCPUUtilization 指标值有所增加,原因是缓慢的命令阻止了 Redis 引擎。有关更多信息,请参阅为什么我发现自己的 ElastiCache for Redis 集群中的 CPU 利用率过高或不断增加?

复杂命令的示例包括:

  • 生产环境中的 KEYS 在大型数据集上扫描整个密钥空间,以搜索指定的模式。
  • 长时间运行的 LUA 脚本

高内存使用率导致的交换量增加

当集群的内存压力增加时,Redis 开始交换页面(使用的内存量超出可用内存)。当内存页面传入和传出交换区域时,延迟和超时问题就会增加。以下是 CloudWatch 指标中交换量增加的指示:

  • SwapUsage 不断增加。
  • FreeableMemory 非常低。
  • BytesUsedForCacheDatabaseMemoryUsagePercentage 指标值高。

SwapUsage 是一种主机级指标,用于指示正在交换的内存量。此指标显示非零值是正常现象,因为它受底层操作系统控制,并且可能受到许多动态因素的影响。这些因素包括操作系统版本、活动模式等。作为一种优化技术,Linux 主动将空闲密钥(客户端很少访问的密钥)交换到磁盘,以便为更常用的密钥释放内存空间。

当可用内存不足时,交换就会成为问题。发生这种情况时,系统开始在磁盘和内存之间来回移动页面。具体而言,SwapUsage 值小于几百兆字节不会对 Redis 的性能产生负面影响。如果 SwapUsage 值较高且正在发生变化,并且集群上没有足够的可用内存,则会对性能产生影响。有关更多信息,请参阅:

网络导致的延迟

客户端和 ElastiCache 集群之间的网络延迟

要隔离客户端和集群节点之间的网络延迟,请使用应用程序环境中的 TCP traceroute 或 mtr 测试。或者,使用诸如 AWSSupport-SetupIPMonitoringFromVPC AWS Systems Manager 文档(SSM 文档)之类的调试工具测试来自客户端子网的连接。

集群已达到网络限制

ElastiCache 节点与相应类型的 Amazon Elastic Compute Cloud (Amazon EC2) 实例共享相同的网络限制。例如,cache.m6g.large 的节点类型与 m6g.large EC2 实例具有相同的网络限制。有关检查带宽能力、每秒数据包数 (PPS) 性能和跟踪的连接这三个关键网络性能组成部分的信息,请参阅监控 EC2 实例的网络性能

要排查 ElastiCache 节点上的网络限制问题,请参阅故障排除 - 与网络相关的限制

TCP/SSL 握手延迟

客户端使用 TCP 连接与 Redis 集群建立连接。创建 TCP 连接需要几毫秒的时间。额外的毫秒数会带来应用程序运行的 Redis 操作的附加开销,并给 Redis CPU 带来更多压力。当集群使用 ElastiCache 传输中加密功能时,控制新连接的数量非常重要,因为 TLS 握手需要额外的时间和 CPU 使用率。快速打开 (NewConnections) 和关闭的大量连接可能会影响节点的性能。可以使用连接池将已建立的 TCP 连接缓存到池中。然后,每次有新客户端尝试连接到集群时,就会重用这些连接。可以使用 Redis 客户端库(如果支持)实现连接池,并且采用适用于应用程序环境的框架,或者从头开始构建框架。还可以使用聚合命令(如 MSET/MGET)作为一种优化技术。

ElastiCache 节点上存在大量连接

最佳实践是跟踪 CurrConnectionsNewConnections CloudWatch 指标。这些指标监控 Redis 接受的 TCP 连接数。大量的 TCP 连接可能会导致很快达到 65,000 的 maxclients 限制。此限制是每个节点可以拥有的最大并发连接数。如果达到 65,000 的限制,则会收到 ERR:已达到最大客户端数的错误。如果添加的连接超出 Linux 服务器的限制或所跟踪的最大连接数限制,则额外的客户端连接会引发连接超时错误。有关预防大量连接的信息,请参阅最佳实践:Redis 客户端和 Amazon ElastiCache for Redis

客户端延迟问题

延迟和超时可能源于客户端本身。验证客户端的内存、CPU 和网络利用率,以确定这些资源是否达到其限制。如果应用程序在 EC2 实例上运行,则利用前面讨论的相同 CloudWatch 指标来检查性能瓶颈。在默认的 CloudWatch 指标无法彻底监控的操作系统中,可能会出现延迟。考虑在 EC2 实例内安装监控工具,例如 atopCloudWatch 代理

如果在应用程序端设置的超时配置值太小,则可能会收到不必要的超时错误。适当配置客户端超时,让服务器有足够的时间处理请求并生成响应。有关更多信息,请参阅最佳实践:Redis 客户端和 Amazon ElastiCache for Redis

从您的应用程序收到的超时错误会揭示更多详细信息。这些详细信息包括是否涉及特定节点、导致超时的 Redis 数据类型名称、发生超时的确切时间戳等。此类信息可帮助您找到问题的模式。使用此类信息可以回答以下问题:

  • 在一天中的特定时间内是否经常发生超时?
  • 超时发生在一个客户端还是多个客户端上?
  • 超时发生在一个 Redis 节点还是多个节点上?
  • 超时发生在一个集群还是多个集群上?

使用这些模式来调查最有可能存在问题的客户端或 ElastiCache 节点。您还可以使用应用程序日志和 VPC 流日志来确定延迟是否发生在客户端、ElastiCache 节点或网络上。

Redis 的同步

Redis 的同步在备份、替换和扩展事件期间启动。这是一种计算密集型工作负载,可能会导致延迟。使用 SaveInProgress CloudWatch 指标来确定同步是否正在进行。有关详细信息,请参阅如何实现同步和备份

ElastiCache 集群事件

查看 ElastiCache 控制台中的 Events(事件)部分,了解观察到延迟的时间段。检查可能由 ElastiCache 托管维护和服务更新引起的后台活动,例如节点替换或失效转移事件,或者是否存在意外的硬件故障。您可以通过 PHD 控制面板和电子邮件收到预定事件的通知。

下面是示例事件日志:

Finished recovery for cache nodes 0001
Recovering cache nodes 0001
Failover from master node <cluster_node> to replica node <cluster_node> completed

相关信息

使用 Amazon CloudWatch 通过 Amazon ElastiCache for Redis 监控最佳实践

诊断延迟问题 - Redis

排查 ElastiCache for Redis 的问题

AWS 官方
AWS 官方已更新 2 年前