生产环境必须用 redis 或 memcached,因 file 驱动在高并发下因文件锁导致排队;cache::remember 默认缓存 null 引发穿透,应改用空值标记策略;cache:clear 不生效多因驱动为 redis 且未指定 store,需用 cache::flush() 或 --store=redis。

缓存驱动选 redis 还是 file?看并发和一致性要求
本地开发用 file 驱动最省事,但上线后高并发下会卡住——file 缓存靠文件锁,多个请求争一个缓存文件时直接排队。生产环境必须切到 redis 或 memcached,它们天然支持原子操作和分布式访问。
配置在 .env 里改一行就行:CACHE_DRIVER=redis。别忘了确认 config/cache.php 中 redis 连接名是否匹配 config/database.php 里的 redis.default 设置,不一致会导致连接失败但报错不明显。
- 小项目、单机部署、无并发压力 → 可用
array(内存级,只在当前请求有效)或file - 需要跨请求/跨进程共享 → 必须
redis或memcached - Redis 连接超时常见于未配
REDIS_PASSWORD或REDIS_PORT写错,默认不是 6379 时尤其容易漏
Cache::remember() 怎么避免缓存穿透和空值误存
用 Cache::remember('user:123', 3600, fn() => User::find(123)) 很方便,但如果 User::find(123) 返回 null,Laravel 默认会把 null 也缓存起来,后续请求全走缓存返回空,形成缓存穿透。
解决方法不是不用 remember,而是加一层判断:
Cache::remember('user:123', 3600, function () {
$user = User::find(123);
if (! $user) {
return Cache::forever('user:123:miss', true); // 存个标记
}
return $user;
});
- 真正查不到时,缓存一个短时效的空标记(比如 60 秒),而不是长期存
null - 别依赖
Cache::has()+Cache::get()两步走,中间可能被删掉,要用原子操作如remember或lock - 缓存 key 命名带业务前缀(如
user:)方便批量清理,别用纯数字或 UUID 当 key
清除缓存时为什么 php artisan cache:clear 不生效
执行命令后还是读到旧数据,大概率是因为你用的是 redis 驱动,而 cache:clear 默认只清 Laravel 自己的缓存前缀(laravel_cache:),但 Redis 里可能混着其他服务的数据,或者你手动用 Redis::set() 写的没走 Laravel 缓存接口。
- 先确认当前驱动:
php artisan tinker --execute="echo config('cache.default');" - 清 Redis 全库(谨慎):
redis-cli FLUSHDB(开发环境可用) - 更安全的做法:用
Cache::flush()在代码里触发,它会尊重当前驱动的清理逻辑 - 如果用了多缓存 store(比如
cache.store('redis')),命令默认不清自定义 store,得指定:php artisan cache:clear --store=redis
模型查询自动缓存?别信封装好的“智能缓存”包
有些第三方包声称能给 Model::find() 自动加缓存,听着省心,实际埋雷:缓存失效时机不可控,关联更新、软删除、事务回滚后缓存不同步,debug 成本远高于手写几行 remember。
真要简化,自己封装一个轻量工具函数即可:
function cachedFind($model, $id, $ttl = 3600) {
$key = $model.'_'.$id;
return Cache::remember($key, $ttl, fn() => $model::find($id));
}
- 模型变更后,主动调用
Cache::forget('user_123')比等 TTL 过期靠谱得多 - 涉及
where查询(非主键)尽量不用缓存,条件组合太多,key 管理成本高,不如优化 SQL 或加数据库索引 - 缓存时间别盲目设长,用户资料类可 1 小时,订单状态类建议 5–30 分钟,越实时的数据缓存越短
缓存不是开关一开就提速,关键是 key 的粒度、失效的时机、和业务状态的耦合程度——这三个地方没对齐,加再快的 Redis 也是假提速。










