
缓存清不掉?先确认你清的是哪个驱动和哪组键
Laravel 的 php artisan cache:clear 默认只清 file 或 database 驱动的缓存,对 Redis 无效——它压根不碰 Redis 里的数据。如果你配了 Redis 但执行命令后缓存还在,大概率是卡在这儿。
实操建议:
- 检查
CACHE_DRIVER环境变量是否确实是redis(不是array或file) - 确认
REDIS_CLIENT是predis还是phpredis,两者在连接池、序列化行为上有差异,影响键名生成 - 用
redis-cli -n 0 keys "laravel*:*" | head -20看实际存在的键,验证是否真在 Redis 里(0是默认 DB,注意REDIS_DB配置) - 清除 Redis 缓存请直接用
php artisan cache:clear --driver=redis,或手动redis-cli -n 0 flushdb
Redis 缓存键名乱、查不到?看 Laravel 怎么拼接前缀和序列化
Laravel 默认会给所有缓存键加前缀(如 laravel_database_),且对值做 serialize()(predis)或 igbinary(phpredis,若启用)。这导致你用 redis-cli get "my_key" 查不到,因为真实键可能是 laravel_database_my_key,值还是二进制。
实操建议:
- 统一配置
CACHE_PREFIX环境变量,避免多实例键冲突(例如设为prod_v2:) - 别在 Redis 中手动 set 带前缀的键——Laravel 取的时候会再套一层前缀,变成双重复合键
- 调试时用
php artisan tinker执行Cache::store('redis')->get('foo'),比直连 redis-cli 更可靠 - 如果要用外部工具查,先看
config/cache.php里的'prefix'和redis连接中的database值
缓存命中率低?检查 store 配置和 forget() 的键是否匹配
很多人用 Cache::put('user:123', $data, 3600) 存,却用 Cache::forget('users.123') 删——键名不一致,删不掉。更隐蔽的是:不同 store(比如 redis vs cache.redis)可能指向不同连接或 DB,导致“以为清了,其实没动到”。
实操建议:
- 所有
put/get/forget显式指定 store:Cache::store('redis')->forget('user:123') - 避免硬编码键名,用常量或辅助函数生成,例如
cacheKey('user', $id)返回"user:{$id}" - 在
config/cache.php中检查stores.redis.connection是否指向正确的 Redis 配置项(默认是default,但你可能改过REDIS_CONNECTION) - 高并发下慎用
Cache::add(),它底层是SETNX,失败时不报错也不提示,容易误判为“缓存未命中”
性能卡在 Redis?关注连接数、超时和序列化开销
Redis 本身快,但 Laravel 每次读写都要走 PHP 客户端、网络、序列化/反序列化三层。特别是大数组或 Eloquent 模型,serialize() 成本明显,且 Redis 内存占用翻倍。
实操建议:
- 把
REDIS_TIMEOUT和REDIS_READ_TIMEOUT从默认0(阻塞)改成1秒,防止单点 Redis 挂掉拖垮整个请求 - 模型缓存优先用
toArray()而非直接存对象,避免序列化闭包、资源句柄等非法内容 - 连接池不是 Laravel 原生支持的,
predis需靠pool配置 +connection_limit,phpredis则依赖phpredis.session.locking等扩展级控制 - 上线前用
redis-cli --latency测延时,超过 2ms 就该查网络或 Redis 配置了
Redis 缓存真正难的不是配通,而是键名管理、序列化边界和连接稳定性——这三个地方一松动,问题就藏得深,还不好复现。











