必须先确认淘汰策略已实际生效,否则所有命中率变化都和策略无关;验证方法是:检查info memory中maxmemory是否非零、evicted_keys是否增长、config get maxmemory*是否双配置均生效,且需结合expired_keys、ops/sec、碎片率等指标交叉判断淘汰行为是否符合预期。

必须先确认淘汰策略已实际生效,否则所有命中率变化都和策略无关。
怎么验证 maxmemory 和淘汰策略是否真正起作用
很多人调了 maxmemory-policy 却没设 maxmemory,结果策略压根不触发。Redis 默认 maxmemory 是 0(不限制),此时无论你配什么策略,都不会淘汰任何 key。
- 用
INFO memory检查used_memory和maxmemory:如果maxmemory显示为 0,说明没生效 - 检查
evicted_keys字段:它记录自启动以来被淘汰的 key 总数,为 0 且内存已满,大概率是策略未触发 - 运行
CONFIG GET maxmemory*确认两个配置都已写入:既要maxmemory非零,也要maxmemory-policy不是noeviction
命中率下降 ≠ 策略错了,先看淘汰是否真在删“冷数据”
比如你从 volatile-lru 切到 allkeys-lfu,但 keyspace_hits / keyspace_misses 计算出的命中率反而跌了,常见原因不是 LFU 本身不好,而是:
- 业务里大量 key 没设 TTL,
volatile-lru原本只动带过期时间的 key,现在allkeys-lfu把长期不访问的永久 key 也纳入淘汰池,误伤了本不该缓存的低频数据 -
maxmemory-samples太小(默认 5),LFU 在采样不足时无法准确识别真实热点,导致高频 key 被误判为低频 - 刚切策略后有“冷启动”窗口:LFU 的频率计数器需要积累访问,前几小时命中率会阶段性偏低,不能单看首小时数据
用 INFO stats 和监控指标交叉比对淘汰效果
光看 keyspace_hits 容易误导,因为它是全局统计,掩盖了淘汰行为对不同 key 类型的影响。更可靠的判断方式是组合以下字段:
-
evicted_keys上升 +expired_keys稳定 → 淘汰策略确实在主动清理,不是靠过期自然释放 -
instantaneous_ops_per_sec在内存接近maxmemory时无明显抖动 → 淘汰过程未造成写阻塞(若抖动剧烈,可能是lazyfree-lazy-eviction未开启) -
mem_fragmentation_ratio> 1.5 且evicted_keys持续增长 → 内存碎片干扰淘汰效率,需结合MEMORY PURGE或重启评估
为什么不能只依赖“命中率数字”做决策
命中率是个合成指标,背后可能掩盖关键问题。例如:
- 某次把
volatile-ttl改成volatile-lru,命中率从 89% 升到 93%,但cmdstat_get中 70% 的请求集中在 3 个 key 上 —— 实际只是这 3 个 key 被保住了,其余缓存价值没变 - 使用
allkeys-random后命中率稳定在 85%,看似还行,但latency doctor显示 GET 延迟 P99 突增,原因是随机淘汰引发大量缓存穿透,后端 DB 压力翻倍 -
noeviction下命中率虚高(98%),但写失败率 12%,业务日志里一堆OOM command not allowed when used memory > 'maxmemory'错误 —— 这根本不是缓存系统在工作
真正要盯的是:淘汰是否发生在预期 key 范围内、后端压力是否同步下降、延迟毛刺是否减少。这些比单一命中率数字更能反映策略是否匹配业务访问模式。











