必须显式设置max_connections,否则默认2**31-1会导致资源泄漏;推荐值=qps×p99 rt×1.2,tp8.0下20常已足够;需配合idle_check_interval与max_idle_time控制空闲回收,并启用health_check_interval=60防僵尸连接。

redis-py 连接池必须设 max_connections,否则默认无上限
不设 max_connections 是连接数失控的第一诱因。redis-py 默认值为 2**31-1,看起来“够用”,但实际会随并发请求持续新建连接,每个连接占用约 120KB 内存,1000 个连接就吃掉 120MB —— 不是性能瓶颈,是资源泄漏。
-
max_connections必须显式设置,推荐值 =(QPS × P99 RT in seconds) × 1.2;例如 QPS=300、P99=15ms → 300 × 0.015 × 1.2 ≈ 6 - 别照搬“50”或“100”这种经验值,TP8.0 下协程密集调用时,连接复用率远高于传统阻塞模型,
max_connections=20往往已足够 - 若用
Redis.from_url()初始化,需在 URL 后加参数:redis://localhost:6379/0?max_connections=20
空闲连接不回收?靠 idle_check_interval + max_idle_time 组合生效
redis-py 没有 idle_timeout 单一参数,必须同时配两个:前者控制检查频率,后者定义“空闲多久该回收”。只设一个等于白设。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
idle_check_interval=30:每 30 秒扫描一次连接池,检查空闲连接 -
max_idle_time=300:空闲超 5 分钟的连接才被回收(注意单位是秒) - 这两个值不能反着设 —— 比如
idle_check_interval=60但max_idle_time=10,那永远扫不到“超时”的连接 - TP8.0 配合协程调度,建议把
idle_check_interval缩短到15,避免大量连接卡在“刚空闲但还没被扫到”状态
TP8.0 下别用 redis.Redis() 直接实例化,改用 with 或显式 close()
TP8.0 的协程生命周期更短、更密集,手动 new 出的 Redis 实例容易在异常路径下漏掉归还逻辑,连接直接卡死在池里。
- 正确写法:
with redis.Redis(connection_pool=pool) as r: r.get("key")—— exit 时自动release() - 如果必须长期持有实例(比如全局单例),务必在应用退出前调用
pool.disconnect(),否则进程结束时连接不会主动关闭 - 绝对不要在循环里反复
redis.Redis(...)—— 每次都新建 client 对象,底层连接池引用计数混乱,release()可能失效
健康检查不是可选项,health_check_interval=60 要开
空闲连接可能处于 TCP half-close 状态(服务端已断但客户端 unaware),is_connected() 仍返回 True,后续 get() 直接报 ConnectionError 或静默失败。TP8.0 下这种问题更隐蔽。
-
health_check_interval=60表示每分钟对空闲连接发一次PING,失败则立即踢出池子 - 别设成
0(默认值),那是彻底禁用健康检查 - 配合
socket_timeout=10使用,避免健康检查本身拖慢主线程 - 若 Redis 部署在 Kubernetes 中且启用了 NetworkPolicy,确认
PING流量未被拦截 —— 否则健康检查全失败,连接池迅速清空
max_idle_time 和 idle_check_interval 差 1 秒,就可能堆积上百个僵尸连接。










