Laravel高并发下缓存雪崩与穿透风险必然存在,需通过随机TTL偏移、空值缓存+分布式锁、布隆过滤器强绑定写入、多级缓存带锁回填四者全局一致防护。

缓存雪崩和穿透在 Laravel 高并发场景下不是“会不会发生”的问题,而是“什么时候爆发”的问题——只要 TTL 集中、key 可被枚举、空值不拦截,三者占其一,风险就已实质存在。
Cache::remember() 的 TTL 必须加随机偏移
固定 TTL 是雪崩的温床。比如 Cache::remember('user_list', 3600, $callback) 在全量 key 上统一过期,凌晨两点整点刷新时 DB 瞬间被打穿。
- 改用动态 TTL:
$ttl = 3600 + rand(-300, 300),再调用Cache::put($key, $value, $ttl) - 所有写缓存入口(包括
remember、put、forever后手动expire)都必须走同一套偏移逻辑,建议封装成CacheHelper::putWithJitter() - 避免对低频 key 也加长 TTL:用户配置类数据可设 25 * 3600(留 1 小时缓冲),但实时排行榜类应控制在 60–120 秒内并强制 jitter
空值缓存必须配合双重检查与锁保护
只写 null 不够,高并发下多个请求仍会同时查库——空值缓存只是“挡第一波”,锁才是“控第二波”。
- 数据库查无结果后,先调用
Cache::put('user:9999', null, 300),再释放锁;不是先释放锁再写缓存 - 读取时不能只判
Cache::get('user:9999') === null就查库,得结合Cache::has('user:9999')确认是否真命中(有些驱动对null存储有歧义) - 若使用 MongoDB 缓存驱动,需确认
MongoStore::get()返回原始存储值,不自动过滤null
布隆过滤器不能只在冷启动时初始化
布隆过滤器一旦漏掉新写入的合法 key,就会把有效请求误判为“不存在”,造成业务丢失。它必须和数据写入强绑定。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 每次
User::create()或->save()成功后,同步调用$bloomFilter->add($user->id) - 删除操作也要调用
$bloomFilter->remove($id)(如果驱动支持),否则过滤器持续膨胀且误判率上升 - 不建议用 Redis Bitmap 自建布隆——Laravel-MongoDB 的
odan/bloom-filter更稳定,容量与误判率可在构造时硬编码,避免运行时抖动
多级缓存回填必须带锁,且 L1 TTL 要远短于 L2
array + Redis 多级缓存不是简单“先查 array 再查 redis”,没锁的回填会让多个进程重复执行相同查询,反而放大 DB 压力。
- L1(array)TTL 设为
5秒,L2(redis)设为1800秒,两者不可倒置,否则本地副本长期不更新 - 回填动作必须包裹
Cache::lock('multi_tier_load:user_'.$id, 10)->block(5),超时直接失败,不阻塞后续请求 - array 层不支持标签或批量清除,所以不要在 array 中存复杂结构;只缓存高频、小体积、低变更的数据,如开关状态、枚举映射表
真正难的不是实现某一个防护点,而是在所有缓存写入路径上保持 jitter、空值、锁、布隆四者的逻辑一致性——漏掉任意一处,就是压垮系统的那个单点。










