先把当时的情况摆出来。Redis 7.2 做缓存和会话共用一套实例,maxmemory 8GB 满了之后把策略从 noeviction 改成 allkeys-lru,第二天一早大量用户被踢下线,日志里会话键查不到,缓存命中率倒是正常。

把日志和配置对完,能解释这个现象的基本就这几处。allkeys-lru 对所有键一视同仁,会话键和缓存键被同等淘汰。少数情况下是会话键没有设置过期时间,被判定为可回收的热数据。

另外,缓存写入量突增,内存压力把最久未用的会话挤出去。少数情况下是主从切换后新主节点的内存更紧张,淘汰更激进。

上来先看当前策略和内存水位

redis-cli config get maxmemory-policy; redis-cli info memory | grep used_memory_human

然后统计会话键的数量与占比

redis-cli --scan --pattern 'sess:*' | head -n 20

接着改成 volatile-lru 只淘汰带过期时间的键

redis-cli config set maxmemory-policy volatile-lru

给会话键补上过期时间并复核

redis-cli ttl sess:8821a3

怎么算真的好了,看的是同一批现象。内存打满时只淘汰缓存键,会话键数量稳定,用户不再被批量踢下线,缓存命中率只小幅下降。

提醒一点。淘汰策略是按整个实例生效的,会话和缓存混部就要选只回收带 TTL 的键,更彻底的做法是拆成两个实例。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189