Redis是ThinkPHP生产环境首选缓存驱动,需配置think-redis扩展、全小写type、整数select及显式空密码;失效策略应分层设计:高一致性数据写后立即删除,静态数据设TTL并主动刷新,批量更新用版本号,关联数据用标签清除;标签名须全小写无特殊字符且仅Redis/file驱动支持;对象缓存必须启用serialize且避免JSON序列化。

ThinkPHP 缓存驱动选 Redis,失效策略按业务分层处理——不是所有数据都该用同一种方式过期。
Redis 驱动是生产环境首选
文件缓存(file)在高并发下易产生 I/O 竞争、锁等待和目录遍历慢等问题,不建议用于线上。Redis 驱动响应快、支持原子操作、天然支持标签(tag)和 TTL,且能与数据库解耦。配置时注意三点:
- 必须安装 topthink/think-redis 扩展,并确保 PHP 已启用
redis模块 -
config/cache.php中'type' => 'redis'必须全小写,'select' => 0必须是整数,空密码也要显式写'password' => '' - 避免多个服务共用一个 Redis DB,否则
Cache::clear()可能误清其它系统缓存;建议单独分配 DB 或使用前缀隔离
缓存失效不能只靠时间,要分场景设计
单一依赖 TTL 容易导致脏读或击穿。应结合业务敏感度选择组合策略:
-
高一致性数据(如用户资料、订单状态):写库后立即
Cache::delete('user:1001'),不等过期 - 中低频静态数据(如文章列表、站点配置):设合理 TTL(如 600–3600 秒),配合主动刷新机制
-
批量更新场景(如后台发布新版本):用版本号控制 key,例如
'article:list:v2',更新时改 v2 → v3,旧 key 自然失效 -
关联数据联动(如用户信息变更影响其文章列表):用
Cache::tag('user_1001')->set(...)标记,后续统一Cache::tag('user_1001')->clear()
标签失效要避开常见坑
ThinkPHP 的 tag() 不是语义分类,而是靠元数据文件或 Redis Hash 映射实现,极易因细节出错而“看似调用了,实则没清”:
立即学习“PHP免费学习笔记(深入)”;
- 标签名必须全小写、无空格、无冒号,
'user_list'✅,'UserList'❌,'user:list'❌ - 设置带标签的缓存必须用
Cache::tag('xxx')->set(),不能用cache('key', $val, $time, ['tag'=>'xxx'])—— 后者无效 - Apcu 和 Memcached 驱动不支持
tag(),开了也白开;只有 file 和 redis 驱动真正生效
对象缓存要序列化,别碰 JSON
缓存 Model 实例、DTO 对象等,必须依赖 PHP 原生 serialize(),不能手动 json_encode():
- JSON 会丢失类名、私有属性、方法、资源句柄,取出来只是
stdClass,调->getName()直接报错 - 确认
config/cache.php中 Redis 驱动配置含'serialize' => true(默认开启) - 别自己再套一层
serialize(),否则get()取出的是字符串而非对象 - 大对象建议缓存
$model->toArray()而非完整实例,减少体积和反序列化开销



















