redis 4.0后不推荐“一刀切”用allkeys-lfu替代allkeys-lru,因lfu与lru逻辑不同:前者依近期访问频次淘汰,后者依最近访问时间;误配会致命中率断崖下跌,关键需匹配业务访问模式。

Redis 4.0 后不推荐“一刀切”用 allkeys-lfu 替代 allkeys-lru,关键看访问模式是否匹配——LFU 不是 LRU 的升级版,而是另一种逻辑的淘汰工具;误配反而会让缓存命中率掉得比 LRU 还快。
LFU 能稳住“真热点”,但对“周期性冷数据”很迟钝
LFU 淘汰依据是「近期访问频次」,不是「最后一次访问时间」。比如一个商品详情页 key 每天被访问 200 次,但凌晨 3 点那波流量过后就再没动过,它在 LRU 下可能几分钟就被踢(因 lru 字段只记分钟级时间戳),但在 LFU 下只要衰减没压垮计数器,就能继续驻留。
- 适合场景:秒杀预热后的爆款、首页 banner、高频配置项等长期高频访问的 key
- 不适合场景:每日定时报表(只在固定时间点刷一次)、用户导出任务扫描的临时 key、TTL 设为 10s 的会话 token(频次低且生命周期短)
- 注意:
volatile-lfu对无 TTL 的 key 完全无效;若你混用了永不过期的配置和带 TTL 的会话,选错策略可能把核心配置干掉
LRU 的“误判”其实可控,LFU 的“污染”更难察觉
很多人抱怨 LRU 把热 key 淘汰了,其实是 maxmemory-samples 太小(默认 5)导致采样偏差大。调到 10 或 20,LRU 表现会明显收敛;而 LFU 的问题更隐蔽:后台批量读(如导出、同步)会抬高大量冷 key 的 logc 计数器,又因衰减慢(默认每分钟一次),这些 key 可能霸占内存数小时。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
lfu-log-factor默认 10,值越小,小频次差异越敏感(比如 1 次 vs 2 次访问更容易区分);值越大,高频 key 更容易“锁死”内存 -
lfu-decay-time控制衰减频率,默认 1 分钟;设为 0 表示禁用衰减——这会让 LFU 退化成静态计数,极易被扫描类操作污染 - 验证方法:
OBJECT FREQ keyname可查当前 logc 值,结合OBJECT IDLETIME对比,能快速识别“高 freq 但 idle 很长”的可疑 key
allkeys-* 和 volatile-* 的选择,比 LRU/LFU 更致命
真正引发线上事故的,往往不是算法本身,而是策略前缀选错。例如:
- 用
allkeys-lru存了永不过期的全局配置 + 带 TTL 的用户 session → 内存紧张时配置可能被清掉,服务直接报错 - 用
volatile-lfu但所有 key 都没设 TTL → 实际等效于noeviction,写入失败却不报警 - 用
volatile-ttl配合不均匀 TTL(有的 30s,有的 2h)→ 刚预热的热 key 因 TTL 短被优先淘汰
如果你的业务里所有 key 都统一设了 TTL(比如全部 30 分钟),volatile-lfu 和 allkeys-lfu 行为几乎一致,但前者语义更安全——至少不会误伤永不过期的关键数据。
LFU 的计数器衰减机制和概率递增设计,让它对“稳定热度”更鲁棒,但也意味着它反应慢、难调试。别只盯着算法名字,先用 redis-cli --stat 观察实际 evicted_keys 增速,再用 MEMORY USAGE 和 OBJECT FREQ 抽样验证 key 级行为——纸上谈兵配出来的 allkeys-lfu,可能正在悄悄拖垮你的缓存命中率。










