Laravel 8应用依赖Redis但无缓存数据的原因及排查方法
为什么应用强制依赖Redis但看不到缓存写入
- 首先排查你查Redis的方式错了:绝大多数情况是你查的是Redis的0号逻辑库,但Laravel允许给不同功能分配独立的Redis逻辑库,打开
config/database.php看redis配置段,每个连接(default、cache、queue、session)都可以单独配置database参数指定库编号,很多项目会把缓存放1号库、队列放2号库、会话放3号库,你用redis-cli连接后默认进入0号库,执行KEYS *当然看不到任何内容。依次执行SELECT 0、SELECT 1、SELECT 2切换库再查询即可,另外注意配置里的prefix参数,Laravel会给所有Redis Key自动加配置的前缀,不要因为Key名和你预期不符就认为不是应用生成的。 - Redis在Laravel里不止用来做缓存,就算你没写任何显式的缓存操作,只要对应功能的驱动配置为Redis,框架底层会自动完成Redis交互,不需要业务代码写Redis调用:
- 会话存储:如果
.env里SESSION_DRIVER=redis,所有用户登录状态、会话数据全存在Redis,框架自动处理读写 - 队列存储:如果
QUEUE_CONNECTION=redis,所有异步任务、延迟任务的调度、执行状态、失败任务记录全存在Redis,框架启动时就会校验Redis连接,连不上直接报错,就算你暂时没触发异步任务也一样 - 限流计数:Laravel自带的
throttle节流中间件(包括登录错误次数限制、接口请求频率限制)默认用Redis做计数存储,只要路由挂载了这个中间件,每次请求都会操作Redis,这类Key大多带短过期时间,你查询的时候可能刚好已经过期 - 原子锁/广播:如果用到了框架的原子锁、缓存锁功能,或者把Redis作为广播驱动,底层也会自动连接Redis
- 会话存储:如果
- 还有少数情况是项目启动校验里硬编码了Redis检查:比如某个服务提供者(Provider)的
boot/register方法里写了Redis连接探活逻辑,应用启动时就会尝试连接Redis,连不上直接抛异常终止运行,哪怕当前业务暂时没实际用到Redis。
如何在代码中定位Redis相关逻辑
- 先从配置入手摸清楚默认使用场景:
先打开根目录的.env文件,查看CACHE_STORE、SESSION_DRIVER、QUEUE_CONNECTION、BROADCAST_CONNECTION这几个配置项的值,如果值为redis,对应功能的Redis操作全是框架底层实现的,不需要业务代码显式调用,这部分不用去业务代码里找。 - 全局检索显式的Redis调用:
- 搜索
Redis::facade调用、redis()全局辅助函数的使用位置,这是业务代码直接操作Redis的入口 - 搜索
Cache::facade、cache()辅助函数的调用,如果CACHE_STORE配置为redis,所有缓存操作本质都是走Redis - 搜索路由、控制器中的
throttle中间件挂载位置,这部分限流逻辑默认走Redis - 检查
app/Providers目录下的所有服务提供者,查看是否有Redis连接校验、Redis实例绑定的相关逻辑
- 搜索
- 最省时间的调试方式:直接用Redis自带的监控能力
连上Redis后执行MONITOR命令,之后再操作页面的所有功能,所有发往Redis的命令、操作的Key、参数都会实时打印在命令行,你可以直接对应到操作触发的Redis逻辑,比逐行翻代码效率高很多。注意调试完成后按Ctrl+C退出MONITOR,这个命令长期运行会带来额外性能开销,不要在生产环境长时间开。 - 新手提醒:不要在生产环境执行
KEYS *命令,这个命令会遍历全量Key,数据量大的时候会直接阻塞Redis服务,日常查Key用SCAN命令更安全。
内容的提问来源于stack exchange,提问作者Artzelij
相关产品推荐
相关产品推荐

