thinkphp多级缓存需手动实现,不自动联动;读取时须显式调用apcu再降级redis并双写,更新时必须双删且先apcu后redis,集群需改用rediscluster驱动并规范hash tag。

ThinkPHP 多级缓存不是自动叠加,而是必须显式声明 store 并手动同步
TP 默认不支持“一级 APCu + 二级 Redis”自动联动,Cache::get() 走的是当前默认 store(比如 redis),不会 fallback 到 APCu;反过来,APCu 里没命中也不会自动查 Redis。所谓“多级”,是靠你在代码里按需调用不同 store 实现的。
配置上要先在 config/cache.php 中定义两个独立驱动:
-
apcu驱动:type 设为apcu,无需 host/port,注意 PHP 必须已启用 apcu 扩展 -
redis驱动:必须显式设置timeout(建议3)、persistent(true)、select(如1)、serialize(推荐igbinary) -
default可设为apcu(优先走本地内存),但业务关键路径应明确指定 store,避免依赖 default
读取时怎么组合 APCu + Redis 实现两级穿透
不能只写 Cache::get($key) ——它只会查当前 store。你要手动控制降级逻辑:
- 先查
Cache::store('apcu')->get($key),命中直接返回 - 未命中再查
Cache::store('redis')->get($key) - 如果 Redis 也未命中,查 DB 后**同时写入两级**:
Cache::store('apcu')->set(...)+Cache::store('redis')->set(...) - 别用
if (!get) { set }三步操作,改用Cache::store('redis')->remember(...)原子写入 Redis,再单独写 APCu
示例片段:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
$key = 'user:123';
$data = Cache::store('apcu')->get($key);
if ($data === null) {
$data = Cache::store('redis')->remember($key, 3600, function () use ($id) {
return Db::name('user')->find($id);
});
// 双写 APCu(注意 TTL 通常比 Redis 短,比如 60s)
Cache::store('apcu')->set($key, $data, 60);
}
写操作必须双删,TP 不会帮你同步
这是最容易出错的地方:更新用户数据后,只执行 Cache::delete($key),删的只是 default store(比如 redis),APCu 里的旧值还在,后续请求从 APCu 拿到的就是脏数据。
- 更新或删除数据时,必须显式调用两级 delete:
Cache::store('apcu')->delete($key)和Cache::store('redis')->delete($key) - 顺序建议先删 APCu 再删 Redis,避免极短时间窗口内 APCu miss 后回源 Redis 拿到刚删掉的旧值
- 如果用了带前缀的 key(如
think:user:123),确保两级 store 的prefix配置一致,否则删错 key - 不要依赖事件监听或钩子自动双删——TP 没内置这种机制,必须手写
集群环境下 Redis store 配置要换用 RedisCluster 类
当 Redis 从单机升级为集群(16384 slots),TP 原生 redis 驱动不支持自动分片路由,直接报 MOVED 错误。你得替换底层连接方式:
- 弃用
type => 'redis',改用type => 'rediscluster'(需 TP ≥ 6.1 且 phpredis ≥ 5.3.0) - 配置项中把
hostname/port换成seeds数组,例如:'seeds' => ['192.168.1.10:7000', '192.168.1.11:7001'] - 禁用
select(集群不支持 DB 切换),timeout和persistent仍需保留 - 注意:集群模式下
MGET、KEYS等跨槽命令不可用,批量操作要用 hash tag(如{user}:123)强制同槽
键名设计更要严格:所有涉及同一业务实体的 key(如用户基础信息、订单列表)必须用相同 hash tag 包裹,否则无法原子批量操作。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










