volatile-lru策略下token被删是因为其只在有ttl的key中按lru淘汰,不区分业务重要性;登录态失效、缓存消失等静默问题由此引发,且淘汰仅在写操作时触发,难以复现和监控。

会直接导致业务数据被无差别删除,且不报错、不告警、难以复现——比如用户登录态突然失效、订单缓存凭空消失、配置项读取为空。
volatile-lru 策略下,为什么我的 token 被删了?
因为你的 token 存在 Redis 里时设置了 EXPIRE 或 SETEX,所以它被归类为 “有 TTL 的 key”;而 volatile-lru 只在这些 key 里按最近最少使用(LRU)淘汰——它不管这个 key 是不是刚生成的、是不是业务核心数据。
常见错误现象:
- 登录后几分钟就掉线,
GET token:abc123返回null,但查TTL token:abc123显示还有 47 小时 - 运维发现
used_memory接近maxmemory,且evicted_keys持续增长 - 用
redis-cli --bigkeys扫不出问题,因为 token 本身很小,但数量极大
关键点:
-
volatile-lru不看业务重要性,只看“多久没被访问过”,token 在用户静默期间(比如打开页面没操作)就可能被踢出 - 如果系统里同时存在大量日志类、监控类、临时任务类的 volatile key,它们会和 token 一起参与 LRU 竞争
- 这种淘汰是静默发生的,
DEL命令不会触发淘汰,只有写操作(如SET、HSET)才会触发
noeviction 和 allkeys-lru 哪个更安全?
noeviction 是默认策略,看似保守,但在生产中反而容易掩盖问题:一旦内存打满,所有写入都返回 (error) OOM command not allowed when used memory > 'maxmemory',服务立刻报错,你马上能感知到;而 allkeys-lru 会默默删掉任何 key(包括没设过期时间的),比如你存的全局配置 config:app、限流计数器 rate:login:192.168.1.100,都可能被顺手清掉。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
使用场景建议:
- 缓存层 + 有强一致要求的场景(如权限配置、开关控制),必须用
noeviction,配合监控告警 + 定期清理逻辑 - 纯读多写少的热点缓存(如商品页 HTML 片段),可选
allkeys-lru,但得确保 key 命名有业务隔离(比如加前缀cache:product:) - 混合型系统(既有 token,又有配置,又有日志),建议拆 Redis 实例,或改用
volatile-ttl+ 合理分散过期时间
如何验证当前策略正在实际生效?
别只看 CONFIG GET maxmemory-policy,要确认它真在干活:
- 执行
INFO stats,检查evicted_keys是否非零且持续增长 - 执行
INFO memory,对比used_memory和maxmemory,差值小于 50MB 时淘汰大概率已激活 - 用
redis-cli -r 100 -i 1 INFO | grep evicted_keys观察每秒淘汰量突增是否匹配业务低峰期(比如凌晨批量任务跑完后)
容易踩的坑:
- 误以为
CONFIG SET maxmemory-policy xxx是热生效——它确实是,但旧 key 不会重排优先级,新策略只对后续写入生效 - 在哨兵或集群模式下,只改了主节点配置,从节点没同步,导致故障时切换后行为不一致
- 用
redis-benchmark测试淘汰效果时,压测 key 全是随机字符串,没模拟真实 key 的访问 pattern,结果误判策略“很稳”
最常被忽略的一点:淘汰策略不是独立起作用的。它和 maxmemory 设置、key 的过期方式(EXPIRE vs PEXPIRE)、客户端连接缓冲区大小、甚至 Linux 的 overcommit_memory 都有关联。线上出问题,永远先查 INFO memory 和 INFO stats 的原始输出,而不是只盯 config 文件。










