使用Redis Pipeline的Go应用客户端连接数暴涨,该行为是否属于正常情况?
这个情况属于异常行为,并非Redis pipeline的正常特性,正常情况下pipeline会复用全局Redis客户端连接池中的连接,不会每次执行都新建连接。
根因分析
- 所使用的go-redis版本存在已知bug:v8.11.5之前的go-redis版本存在pipeline执行后连接未正常归还连接池的问题,每次执行pipeline都会向连接池申请新连接,最终耗尽连接池配额
- Redis默认连接池配置未做优化:go-redis默认
PoolSize为CPU核心数*10,若服务器为16核配置默认池大小就是160,并发goroutine调用pipeline时会快速打满连接池,且默认IdleTimeout为0,空闲连接不会被主动回收,最终连接数持续上涨 - 代码使用不规范:给出的示例代码中pipeline执行后未调用
Close()方法显式释放连接占用,部分版本中仅执行Execute()不会主动触发连接归还逻辑
修复方案
- 优先升级go-redis到最新稳定版本,推荐选择v9+版本,官方已修复pipeline连接泄漏的相关问题
- 自定义Redis连接池配置,不要直接使用默认值,参考配置示例:
import "time" rdb := redis.NewClient(&redis.Options{ Addr: "your_redis_addr:6379", Password: "your_redis_password", DB: 0, PoolSize: 20, // 按需设置合理的连接池上限,避免无限制新建连接 IdleTimeout: 5 * time.Minute, // 空闲超过5分钟的连接自动回收 MaxConnAge: 30 * time.Minute, // 连接最长生命周期,到期强制关闭重建 MinIdleConns: 2, // 维持最小空闲连接数,避免冷热切换时频繁新建连接 })
- 规范pipeline使用代码,执行完后显式调用
Close()释放资源:
pipe := rdb.Pipeline() defer pipe.Close() // 新增defer语句保证pipeline资源被释放 pipe.Set(ctx, "hi", "hi") _, err := pipe.Execute() if err != nil { // 自行处理错误逻辑 }
- 若并发调用pipeline的goroutine数量非常高,建议对goroutine做并发限流,避免短时间内同时向连接池申请大量连接
修复完成后可通过Redis的CLIENT LIST命令查看连接的空闲时间,确认空闲连接会正常回收,连接数最终稳定在设置的PoolSize范围内。
内容的提问来源于stack exchange,提问作者MHCH
相关产品推荐
相关产品推荐

