优先选 Redis 驱动:支持原子操作、TTL 自动清理、复杂数据结构;file 驱动在 QPS 超 20 时易因文件锁阻塞。需配置 prefix 防键冲突,慎用 Cache::remember() 的副作用逻辑,推荐 Cache::tags() 批量管理缓存,TTL 用语义化表达而非硬编码秒数。

缓存驱动选 redis 还是 file?看并发和数据结构需求
Laravel 默认用 file 驱动,本地开发够用,但一上生产就容易卡住——尤其多请求同时写缓存文件时,会触发文件锁,Cache::put() 可能阻塞几秒。真实线上场景下,只要 QPS 超过 20,file 就该换掉。
redis 是最稳妥的替代:支持原子操作、TTL 自动清理、还能存数组/对象(序列化后)。但注意两点:
- 不要用
phpredis扩展的Redis::setex()直连 Redis,绕过 Laravel 缓存抽象层,否则Cache::remember()的回调逻辑、标签(tags)功能全失效 - 如果用
redis驱动但没配prefix,多个 Laravel 应用共用一个 Redis DB 时会互相污染缓存键
示例配置(config/cache.php):
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'prefix' => 'laravel_cache:',
],
Cache::remember() 里别写数据库查询以外的副作用逻辑
这个函数本意是“查缓存 → 没命中 → 执行闭包 → 存缓存”,但很多人在里面塞日志、发通知、改状态——结果缓存命中时这些逻辑就不执行了,行为不一致。
常见错误现象:
- 用户注册后发欢迎邮件,代码写在
Cache::remember('welcome_emailsent'.$uid, 3600, fn() => { Mail::to(...)->send(); return true; })里 → 第二次访问直接返回true,邮件再也不会发 - 后台任务计数器用
Cache::remember('task_count', 60, fn() => Task::where('status', 'pending')->count())→ 缓存期间新增任务不会被统计
正确做法:只放纯查询、无状态、可重复执行的逻辑。如果必须带副作用,拆成两步:先查缓存,没命中再手动执行副作用 + 写缓存。
缓存键命名别用动态 ID 拼接,优先走 Cache::tags()
直接拼键如 'userprofile'.$id 看似简单,但一旦要批量清除(比如用户修改头像后清掉所有相关缓存),就得遍历或用 Redis 的 KEYS userprofile* ——线上禁用,会阻塞主线程。
Cache::tags() 是 Laravel 提供的轻量级分组机制,底层靠前缀 + 集合维护,清除时只删 tag 元数据,不扫全库:
- 写缓存:
Cache::tags(['user', 'profile'])->put("{$id}", $data, 3600) - 清单个用户:
Cache::tags(['user'])->flush()或更细粒度Cache::tags(['user', 'profile'])->forget("{$id}")
但注意:
-
tags()在redis驱动下可用,在database或file驱动下会退化为全表扫描或全目录遍历,性能极差 - 标签名别带变量,比如
Cache::tags(['user_'.$id])——这就又回到键名爆炸的老问题,失去了 tag 的聚合意义
缓存时间别硬写数字,用 now()->addMinutes(30) 替代 1800
Cache::put('key', $value, 1800) 这种写法看着省事,但 1800 秒 = 30 分钟,谁还记得?下次要调成 45 分钟,得翻文档算秒数;更麻烦的是,不同地方用同样数值但语义不同(比如 1800 有时是“登录态”,有时是“商品列表”),后期根本没法统一管理。
推荐封装常量或辅助函数:
- 在
App\Support\CacheTtl.php里定义:class CacheTtl {<br> public const USER_PROFILE = 1800; // 30 分钟<br> public const PRODUCT_LIST = 300; // 5 分钟<br> } - 或直接用 Carbon:
Cache::put('key', $value, now()->addMinutes(30)),语义清晰,且 Laravel 内部会自动转成秒数
容易被忽略的一点:缓存时间不是越长越好。静态资源(如配置项)可设 24 小时,但用户数据类缓存超过 10 分钟,就大概率出现「用户改完资料,页面刷新还显示旧头像」的问题——这不是缓存没刷新,是它本就不该缓这么久。











