直接换cache.handler为redis或memcached后性能变差,大概率是连接未生效、缓存键含随机查询参数导致命中率低,或ttl设置过短/未设,致使缓存未真正启用。

直接换 cache.handler 从 file 改成 redis 或 memcached 后性能反而变差,大概率不是缓存本身的问题,而是配置或使用方式没对齐新驱动的特性。
Redis/Memcached 连接未真正生效
很多项目改完 .env 里的 cache.handler = redis 就以为搞定了,但实际请求仍走 file 驱动——因为底层连接失败时,CodeIgniter 4 会自动 fallback 到 backupHandler(默认是 dummy,即不缓存),而你可能根本没看到报错。
- 检查 PHP 是否已加载
php-redis或php-memcached扩展:php -m | grep redis - 确认 Redis 服务正在运行:
redis-cli ping应返回PONG - 在
app/Config/Cache.php中显式设置$backupHandler = 'file',再试一次,如果性能回升,说明原先是 fallback 导致完全没缓存 - 临时加一行日志验证当前 handler:
var_dump(cache()->getHandler()::class);
缓存键生成逻辑与旧版不兼容
CI4 的页面缓存键默认包含完整 URI(含查询参数),而 CI3 默认忽略 query string。如果你从前端发大量带随机参数(如 ?v=123456)的请求,CI4 会为每个参数生成独立缓存项,导致缓存命中率暴跌。
- 在
app/Config/Cache.php中设$cacheQueryString = false,禁用 query string 参与 key 生成 - 若需保留部分参数(如分页
?page=2),可传数组:$cacheQueryString = ['page', 'limit'] - 避免在控制器里手动拼接带时间戳、随机数的 URL,这类 URL 天然无法复用缓存
ttl 设置过短或未设,缓存形同虚设
CI4 默认 $ttl = 60(秒),对多数静态页面或 API 响应来说太短;更常见的是,开发者调用 cache()->save() 时漏传 $ttl 参数,导致使用全局默认值,而该值可能被无意覆盖为 0 或负数。
- 检查
app/Config/Cache.php中的$ttl是否被设为0或false(等价于不缓存) - 显式指定 TTL:比如
cache()->save('user_profile_123', $data, 300)(5 分钟) - 对高频但低变动数据(如站点配置),可设为 3600+;对用户级数据,建议控制在 60–300 秒内
- 用
redis-cli keys "ci4_*"查看实际缓存项存活时间,确认是否真被写入且未秒删
真正卡住性能的,往往不是“用了什么缓存”,而是“缓存有没有被真正用上”——连接通了、key 稳了、ttl 活着,三者缺一不可。尤其要注意 CI4 对 query string 的默认处理和 fallback 行为,这两点最容易被忽略。











