调大max_connections仍报wait timeout,主因是wait_timeout值过小(如1.0–2.0秒)导致协程排队超时,而非连接数不足;需同步调高wait_timeout、设置min_connections防冷启动延迟、确保float类型解析,并排查pipeline/transaction连接泄漏。

为什么调大 max_connections 还是报 wait timeout
不是加了就管用。常见错误是只改了 max_connections,但 wait_timeout 仍卡在 1.0 或 2.0 秒——协程排队等连接的时间上限太短,稍有延迟(比如某次 Lua 脚本执行慢了 300ms)就会直接超时抛 WaitTimeoutException,根本等不到连接释放。日志里反复出现 “wait timeout”,但 SHOW PROCESSLIST 看不到堆积连接,说明问题不在 DB,而在 Redis 连接池本身。
怎么算够用的 max_connections 值
别拍脑袋设 200。真实需求得按峰值 QPS × 平均耗时 × 余量来估算:
- 先用
hyperf:redis:pool:stats命令或 Prometheus 指标查当前used_connections峰值 - 若线上压测跑出 120 QPS,平均 Redis 耗时 80ms,则理论需 120 × 0.08 = 9.6 个连接
- 必须加 2–3 倍余量防抖动,建议起步设 30–50;单机多 Worker(如 8 个)且混用 cache/queue 场景,可设到 80
- 注意:MySQL 的
max_connections是 151,默认不等于 Redis 池能设多少——Redis 池要单独配,不能复用同一数值
配置里最容易漏掉的三个点
config/autoload/redis.php 中光写 'max_connections' => 50 不够,还必须确认:
-
min_connections是否设了(建议 5–10),否则冷启动时每次都要新建连接,放大首屏延迟 -
wait_timeout类型是否为 float(比如写成'wait_timeout' => (float) env('REDIS_WAIT_TIMEOUT', 3.0)),否则可能被当字符串解析导致行为异常 - 是否用了 pipeline/multi 却没兜住异常——
try { $redis->pipeline()->set(...)->get(...); throw new Exception(); } catch () {}会导致连接泄漏,池子越用越小
验证改完有没有真生效
重启服务后别只看日志有没有错,要抓实时数据:
- 执行
php bin/hyperf.php hyperf:redis:pool:stats,检查current_used和max_used是否贴近你设的max_connections - 用
swoole_get_local_socket_count()或ss -s | grep ESTAB观察进程级 TCP 连接数是否稳定,避免 fd 泄漏 - 如果
current_used长期 > 90% 且wait_timeout错误仍在,大概率是 pipeline/transaction 没正确释放,不是池子不够
hey -z 30s -q 100 http://api/xxx 这类工具按真实节奏压测,而不是只看单接口 RT。


















