redis连接配置需同步修改config/database.php和config/cache.php并执行php artisan config:clear;单机用redis驱动,集群才用redis-cluster;缓存更新应主动失效而非依赖ttl;内存超限时需调整maxmemory-policy并加key前缀防冲突。

Redis连接配置写在.env里但不生效?
常见现象是改了REDIS_HOST或REDIS_PORT后php artisan tinker里Cache::get('test')还是连本地127.0.0.1:6379。根本原因是Laravel不会自动重载缓存配置——它在启动时就从config/cache.php读取驱动参数,而这个文件里redis部分默认硬编码了'host' => env('REDIS_HOST', '127.0.0.1'),但实际调用时走的是config/database.php里的redis配置块。
正确做法是确保两处一致:
-
config/database.php中'redis'下的'default'连接必须和.env里REDIS_*变量对应 -
config/cache.php中'stores.redis.connection'要设为'default'(不是'cache'或其他名字) - 改完运行
php artisan config:clear,别漏掉这步
缓存驱动选redis还是redis-cluster?
单机Redis或主从部署用redis驱动就够了;只有真正用了Redis Cluster(至少3主3从)才需要redis-cluster。后者会绕过Laravel的默认键哈希逻辑,直接交由客户端分片,但代价是不支持Cache::tags(),且SCAN类命令不可用。
性能差异明显:单机场景下redis驱动比redis-cluster快15%~20%,因为少一层集群路由判断。验证方式很简单:
- 看
config/cache.php里'default' => 'redis' - 检查
config/database.php中'redis.default'是否指向单节点配置 - 用
redis-cli -h your-host info | grep role确认没启用cluster模式
Cache::remember缓存时间设太长导致数据不一致?
这不是Redis的问题,是业务逻辑没对齐。比如用户资料页用Cache::remember('user_'.$id, 3600, fn() => User::find($id)),但后台管理员刚更新了该用户邮箱,前端仍显示旧值,直到一小时后缓存过期。
解法不是缩短TTL,而是主动失效:
- 在
User模型的updated事件里加Cache::forget('user_'.$this->id) - 如果用到了缓存标签(
Cache::tags(['users'])->put(...)),更新时用Cache::tags(['users'])->flush() - 避免对高变动数据(如实时库存、未读消息数)设>60秒的TTL
注意:Cache::remember底层用GET+SETNX组合,若回调函数抛异常,缓存不会写入——这点常被忽略。
Redis内存爆满后Laravel直接报Connection refused?
这其实是OOM Killer干的——当Redis内存超限且maxmemory-policy设为noeviction时,Redis会拒绝写入,但Laravel的Predis\Client默认不处理READONLY或OOM command not allowed这类错误,直接断连。
必须做两件事:
- 进Redis服务器执行
CONFIG SET maxmemory-policy allkeys-lru(开发环境可临时用),生产环境建议配volatile-lru并严格设TTL - 在
config/database.php的redis.default.options里加'prefix' => env('REDIS_PREFIX', 'laravel_').env('APP_ENV', 'local').':',避免不同环境缓存key撞车挤占内存 - 上线前用
redis-cli --bigkeys扫一遍大key,尤其警惕Cache::put('all_posts', $hugeCollection)这种操作
最麻烦的是,有些大key删不掉——比如序列化后的Eloquent Collection含大量冗余关系,得先toArray()再缓存。











