调试 Go Redis

连接池大小

为了提高性能,go-redis 会自动管理一个网络连接(套接字)池。默认情况下,连接池大小为 runtime.GOMAXPROCS 报告的每个可用 CPU 10 个连接。在大多数情况下,这已经足够了,调整它很少有帮助。

rdb := redis.NewClient(&redis.Options{
    PoolSize: 1000,
})

redis: 连接池超时

当连接池中没有空闲连接可用,并且持续时间超过 Options.PoolTimeout 时,您可能会遇到此错误。如果您正在使用 redis.PubSubredis.Conn,请确保在不再需要时通过调用 Close 方法正确释放 PuSub/Conn 资源。

当 Redis 处理命令的速度太慢,并且连接池中的所有连接都被阻塞超过 PoolTimeout 时间时,您也可能会遇到此错误。

超时

即使您正在使用 context.Context 时限,也请不要禁用 DialTimeoutReadTimeoutWriteTimeout,因为 go-redis 在不使用上下文的情况下执行一些后台检查,而是依赖于连接超时。

如果您正在使用 AWS 或 Google Cloud 等云提供商,请不要使用小于 1 秒的超时。这种小的超时在大多数情况下都能正常工作,但在云比平时更慢的情况下会惨败。有关详细信息,请参阅 Go 上下文超时可能是有害的在新窗口中打开

如果您遇到了此错误,还可以参阅 上下文时限已超过在新窗口中打开

大量打开的连接

在高负载下,某些命令会超时,go-redis 会关闭这些连接,因为它们仍然可以稍后接收一些数据,并且不能重复使用。关闭的连接首先进入 TIME_WAIT 状态,并保持该状态,直到最大段生命周期结束的两倍时间,通常为 1 分钟。

cat /proc/sys/net/ipv4/tcp_fin_timeout
60

为了解决这个问题,您可以增加读写超时或升级服务器以处理更多流量。您还可以增加最大打开的连接数,但这不会使您的服务器或网络更快。

有关一些建议,还可以参阅 应对 TCP TIME-WAIT在新窗口中打开

管道

由于 go-redis 大部分时间都花在从连接中写入/读取/等待数据上,因此您可以通过使用 管道 同时发送多个命令来提高性能。

缓存

如果您的应用程序逻辑不允许使用 管道,请考虑为最常用的操作添加一个本地进程内 缓存,例如使用 TinyLFU。

硬件

确保您的服务器具有良好的网络延迟和具有大型缓存的快速 CPU。如果您有多个 CPU 内核,请考虑在一台服务器上运行多个 Redis 实例。

有关更多详细信息,请参阅 影响 Redis 性能的因素在新窗口中打开

分片

您还可以将数据拆分到多个 Redis 实例中,以便每个实例包含键的子集。这样,负载就会分布在多个服务器上,并且您可以通过添加更多服务器来提高性能。

如果您正在使用 Redis 进行缓存,并且可以承受丢失一些数据,则 Redis 环 是一个不错的选择。否则,您可以尝试 Redis 集群

监控

监控 Redis 数据库的性能对于维护系统整体的健康状况、效率和可靠性至关重要。适当的性能监控有助于识别和解决潜在的问题,防止它们导致服务中断或性能下降。

Uptrace 是一个 OpenTelemetry 后端在新窗口中打开,支持分布式跟踪、指标和日志。您可以使用它来监控应用程序并排查问题。

Uptrace Overview

Uptrace 提供直观的查询构建器、丰富的仪表板、带有通知的警报规则以及大多数语言和框架的集成。

Uptrace 可以在一台服务器上处理数十亿个跨度和指标,并允许您以 10 倍的低成本监控您的应用程序。

您只需几分钟即可尝试 Uptrace,方法是访问 云演示在新窗口中打开(不需要登录)或使用 Docker在新窗口中打开 在本地运行它。源代码在 GitHub在新窗口中打开 上可用。