多级缓存是l1(本地内存)与l2(redis)分工协作的架构,通过array拦截高频读、redis保障跨进程一致,配置multi_tier驱动并分层设置ttl(l1为5秒、l2为30分钟),读取加锁防击穿,结合空值缓存、布隆过滤防穿透,支持标签清理与降级熔断提升韧性。

多级缓存不是简单堆叠两层存储,而是通过本地内存(L1)与分布式缓存(L2)分工协作,在高并发下兼顾速度、一致性与容错性。核心是让高频重复读走快路径,跨进程共享和持久化交给稳路径。
搭建 L1(array)+ L2(Redis)双层结构
本地 array 缓存拦截同一请求内或短时间内的重复读取,避免每次穿透到 Redis;Redis 作为共享层保障数据在多个 PHP 进程间一致,并支持失效、标签等高级能力。
- 在 config/cache.php 中新增自定义驱动:
multi_tier,设'primary' => 'array'、'fallback' => 'redis' - 创建 App\Cache\MultiTierStore 类,继承
Illuminate\Cache\Repository,重写get():先查 array,未命中再查 Redis 并回填 - 确保 .env 中设置
CACHE_DRIVER=multi_tier,且 Redis 连接配置正确可用
分层设置 TTL 防止脏数据滞留
L1 和 L2 的过期时间不能相同。L1 要极短(如 5 秒),保证本地副本不会长期偏离真实值;L2 可按业务设合理周期(如 30 分钟),兼顾时效与稳定性。
- 重写
put()方法:对 array 层调用Cache::store('array')->put($key, $value, 5);对 Redis 层调用Cache::store('redis')->put($key, $value, 1800) - 读取时若 array 返回 null 或已过期,需加锁再查 Redis,防止多个请求同时触发源查询——用
Cache::lock('multi_tier_load:'.$key, 10)->block(5)包裹加载逻辑
用空值缓存 + 布隆过滤防穿透
当大量请求查询数据库中不存在的 key(如非法 ID),若不做处理,会全部打到 DB,造成缓存穿透。L1+L2 架构可在此基础上叠加防护。
- 对确认不存在的数据,也缓存一个特殊标记(如
null或'MISS'),TTL 略短于正常数据(如 60 秒),避免无效查询反复冲击 - 在 L1 层前置布隆过滤器(Bloom Filter):初始化加载白名单或热 key,请求先过 filter,大概率拦截非法 key,不进后续流程
- 注意布隆过滤器有误判率,仅作快速拒绝,不能替代业务校验
配合标签与降级熔断提升韧性
多级缓存不只是提速,更要扛住异常。L2(Redis)支持标签批量清理,L1 可按前缀同步清理;当 Redis 不可用时,L1 仍可短暂兜底,避免全链路雪崩。
- 写入时统一走
Cache::tags(['user'])->put('user_123', $data, 3600),更新时用Cache::tags(['user'])->flush()清除关联项,并主动清对应 L1 前缀(如arraystore 中所有user_*键) - 在 L1 查询失败或 L2 连接异常时,自动降级为只读 L1(如有)、或返回默认值/旧缓存,同时记录告警,不阻塞主流程
- 可引入简单计数器:连续 N 次 L2 失败后,自动切换为 L1-only 模式,直到健康检查恢复











