volatile-lru/lfu不工作根本原因是只淘汰带ttl的键,若数据全为永久键(ttl=-1)则策略失效,内存满时如noeviction般报oom错误;须检查ttl分布并改用allkeys策略。

为什么volatile-lru或volatile-lfu根本没反应
这类策略只对带TTL的key生效,如果业务写入全是SET user:1001 "Alice"这种没加过期时间的永久键,Redis会直接跳过淘汰逻辑,表现和noeviction一样——报OOM command not allowed when used memory > 'maxmemory'。不是配置错了,是数据不匹配策略。
验证方法:SCAN 0 MATCH * COUNT 1000后对每个key执行TTL keyname,返回值普遍为-1(永久)就坐实了这个问题。
- 检查所有缓存写入路径,确认是否漏掉
EXPIRE、SETEX或SET ... EX等带过期参数的操作 - 若业务确实需要永久键(如配置项),必须改用
allkeys-lru或allkeys-lfu - 临时排查可快速执行
redis-cli --scan | xargs -L 1 redis-cli TTL | grep -v "^-2$" | sort | uniq -c | sort -nr看TTL分布
evicted_keys始终为0,但内存已满
说明淘汰机制压根没触发,常见原因有三个:策略设成noeviction(默认值)、maxmemory没设或设为0、或者碎片率过高导致实际可用内存远低于理论值。
先运行INFO memory,重点看这几项:
-
used_memory≥maxmemory→ 确认内存上限已生效 -
mem_fragmentation_ratio> 1.5 → 碎片严重,需重启实例或启用activedefrag yes -
evicted_keys== 0 且maxmemory_policy不是noeviction→ 检查key是否有TTL(见上一节)
注意:CONFIG GET maxmemory-policy返回值只是配置项,不代表正在运行;真正要看evicted_keys是否增长。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
如何确认淘汰策略真在工作
不能只信配置,得看行为。最直接的证据是evicted_keys持续增加,同时used_memory稳定在maxmemory附近波动(而非一路冲顶)。
- 每5秒执行一次
INFO memory | grep -E "(used_memory|evicted_keys|maxmemory)",观察evicted_keys是否递增 - 对比
used_memory_peak和当前used_memory:若前者显著更高,说明淘汰确实在释放空间 - 开启慢日志捕获淘汰动作:
CONFIG SET slowlog-log-slower-than 0,然后SLOWLOG GET 10,筛选含evict的条目
如果evicted_keys不动但used_memory缓慢下降,大概率是后台在清理过期key(定期删除),不是淘汰策略在起作用。
allkeys-lru和allkeys-lfu选哪个
两者都无TTL限制,但行为逻辑不同:allkeys-lru依赖最近访问时间,适合会话类短期热点;allkeys-lfu依赖访问频次,适合长尾+强热点场景(如首页Banner被查1000次,冷门页只查1次)。
-
allkeys-lru是随机采样5个key后淘汰空闲最久的,不是全量扫描,有小概率误删 -
allkeys-lfu用4位计数器+周期衰减,超高频访问可能溢出,计数精度有限 - 写多读少或突发流量打爆个别key时,
allkeys-lfu通常比allkeys-lru更稳
真正容易被忽略的是策略与数据生命周期的错配——比如用allkeys-lfu存临时Token,结果因频次低被秒删;或用volatile-lru存用户资料却忘了加EX,等于白配。










