thinkphp 5.1 默认无 redis 连接池,每次调用 cache::store('redis') 可能新建连接,高并发下 tcp 握手与认证开销拖垮性能;需配置 'persistent' => true、php.ini 开启 redis.pconnect = 1,并设 timeout 与 select 隔离库号。

ThinkPHP 5.1 默认没有 Redis 连接池
直接调用 Cache::store('redis') 每次都可能新建连接,尤其在循环、高频接口或未复用实例时,TCP 握手 + 认证开销会迅速拖垮性能。这不是“配置没开”,而是框架层根本没实现连接池逻辑 —— 它依赖底层扩展(phpredis 或 predis)自己管理复用。
启用 phpredis 持久连接是最简生效方案
适用于 Nginx + PHP-FPM 部署,改两处即生效,不改代码:
- 在
config/cache.php的 redis store 配置中显式加'persistent' => true和'persistent_id' => 'tp51_redis_pool'(避免不同配置混用同一连接) - 确认
php.ini中已开启redis.pconnect = 1(否则pconnect()不生效) - 必须设置
'timeout' => 2.5和'read_timeout' => 2.5,否则超时会卡满系统默认值(可能达 60 秒) - 搭配
'select' => 0显式指定库号,防止与 session 或其他服务冲突
绕过 Cache 层手动初始化 Predis 单例
当 Cache 封装干扰你控制连接生命周期时(比如需要长连接、Pub/Sub、或避免 Cache::store() 多次调用),直接接管更可靠:
- 执行
composer require predis/predis - 在服务提供者或容器启动时绑定单例:
Container::getInstance()->bind('redis', function () { return new \Predis\Client([ 'scheme' => 'tcp', 'host' => config('redis.host'), 'port' => config('redis.port'), 'password' => config('redis.password'), 'connection_timeout' => 1, 'read_write_timeout' => 2.5, 'retry_interval' => 100, ]); }); - 业务中统一用
app('redis')->get('key'),彻底避开Cache::get()的中间层开销
ThinkPHP 8 的 cache/session 隔离必须显式配 database
很多人以为共用一个 Redis 实例没问题,结果缓存和 session key 冲突、GC 清 session 时误删缓存 —— TP8 不自动隔离:
-
config/cache.php中 redis store 必须写明'database' => 0 -
config/session.php中 redis store 必须写明'database' => 1(不能留空或依赖默认) - 如果只能共用 database,两个配置里都得加
'prefix' => 'cache_'/'prefix' => 'sess_',且 prefix 值不能相同 - ACL 模式下,密码字段名是
'auth' => 'xxx',不是'password',否则连接成功但 set 失败且无报错
真正容易被忽略的是:连接池效果高度依赖服务端配合。哪怕客户端全配对了,Redis 的 maxclients 不够、系统 ulimit -n 未调大、或 tcp-keepalive 关闭,连接照样堆积泄漏 —— 这些不在 PHP 代码里,但决定你配得再好也扛不住压测。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











