如何使用问小白排查Redis缓存失效
针对Redis缓存失效问题,通过四次精准排查定位根因:确认键是否存在,检查清除命令或淘汰策略,分析TTL及过期配置,验证请求是否被绕开或连接异常,无需监控平台即可覆盖90%场景。
先说说缓存穿透——请求的数据在Redis和数据库里都不存在,结果每次请求都直接怼到数据库上,压力瞬间飙升。成因嘛,无非是非法参数、恶意攻击、业务校验没做全。解决办法也老生常谈:参数校验、缓存空值、布隆过滤器。但问题来了:当你发现线上服务突然变慢、数据库压力飙升、大量请求直扑后端,而Redis里本该有的缓存键却查不到——这不是“过期了”,而是缓存被清空、穿透、击穿或配置异常导致的失效。好,接下来我们用最直白的问题链倒推根因:不依赖监控平台,不写一行代码,只靠三次精准提问加一次验证动作,就能定位90%的缓存失效问题。

第一步:确认缓存键是否真的丢失
打开redis-cli,连上对应实例,执行exists your_cache_key(比如exists token:abc123)。如果返回0,说明键确实不存在;如果返回1,但get your_cache_key出来是空字符串或null,那可能是缓存了空值,并非丢失。
注意:别只查一个key——挑3~5个近期高频访问的key批量验证,避免误判单个key过期为全局失效。
第二步:排查“谁删除了数据”
在redis-cli中执行monitor命令,保持窗口开着,等10~15秒,观察是否有flushall、flushdb、del批量操作出现。一旦看到这类命令,立刻Ctrl+C中断,再查info clients看client list里的IP和端口,结合应用日志定位发起方。
【关键陷阱】容器化部署时,monitor输出可能被重定向到日志文件,直接在宿主机tail -f /data/logs/redis/monitor.log更可靠。
如果没看到清除命令,转去查info stats里的evicted_keys和expired_keys数值。若evicted_keys持续增长,说明内存不足触发了淘汰策略;若expired_keys突增,才是真正的集中过期。
第三步:检查缓存键的过期时间设置
方法一:查key的剩余生存时间
执行ttl your_cache_key。如果返回-2,代表key不存在;返回-1,代表key永不过期;返回正数,才是真实剩余秒数。对一批key批量执行ttl,看是否集中在某几分钟内归零——这是雪崩前兆。
方法二:翻代码找过期逻辑
搜索项目里所有setex、expire、@Cacheable(expire = ...)调用点。重点检查是否用了固定值(如3600),而不是带随机偏移的3600 + new Random().nextInt(600)。
方法三:看配置文件是否被覆盖
进Redis服务器执行config get maxmemory和config get maxmemory-policy。如果maxmemory设得太小(比如512MB),而maxmemory-policy是noeviction,就会导致写入失败而非淘汰——此时set命令返回错误,缓存根本没存进去。
第四步:验证缓存是否被绕过
第一步:模拟穿透请求
用curl发一个明显不存在的key请求,比如curl "http://api.example.com/orderid=9999999999",同时在Redis里监控incr miss_count_order_9999999999是否被创建。如果没创建,说明空值缓存逻辑压根没走。
第二步:抓包看实际流向
在应用服务器上执行tcpdump -i lo port 6379 -w redis.pcap,复现一次请求,然后用Wireshark打开pcap文件,过滤redis协议,确认请求是否真的发到了Redis端口——很多“缓存失效”其实是DNS解析失败、连接池耗尽或客户端配置指向了错误实例。
第三步:查Shiro/Spring Security拦截器
如果你用Shiro集成Redis做session存储,检查SecurityManager配置里cacheManager是否被替换成ConcurrentMapCacheManager——这种内存缓存会和Redis完全脱钩,所有缓存操作都在JVM里完成,Redis里自然空空如也。
