最常见的误操作是改完配置立即查object freq,而lfu计数器只在get/set等真实访问时按概率更新,并非实时刷新;新key初始值恒为5,且增长概率极低(如factor=100时counter=5的增量概率仅约0.002),需多次访问才可能变化。

为什么改了 lfu-log-factor 却看不到 OBJECT FREQ 变化
最常见的误操作是:改完配置就立刻查 OBJECT FREQ mykey,发现还是 5 或 0。这不是配置没生效,而是 LFU 计数器只在真实访问(如 GET、SET)时按概率更新,不是实时刷新的。
新 key 的初始计数器固定为 LFU_INIT_VAL(默认 5),第一次 GET 也不一定 +1 —— 增长是概率行为。比如 counter=5、lfu-log-factor=100 时,增长概率约 0.002,平均要访问 500 次才触发一次 +1。
- 必须确认
CONFIG GET maxmemory-policy返回的是volatile-lfu或allkeys-lfu,否则所有 LFU 配置都不起作用 - 刚
SET的 key 返回OBJECT FREQ为 5 是正常行为,不是 bug -
OBJECT FREQ是快照,受后台衰减、counter 是否饱和(255)、最近是否被访问共同影响,不能当累加器用
怎样根据业务访问分布选 lfu-log-factor 值
这个参数本质是在“早识别冷 key”和“稳住真热 key”之间做权衡,没有通用最优值,必须结合你的热点分布形态来定。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 大量中低频 key(如用户个性化配置)+ 偶尔冒出新热点(如活动页)→ 用
lfu-log-factor 1~5:让新 key 的 counter 快速从 5→6→7,避免被误淘汰 - 核心数据高度集中(如商品 ID、登录 token),且长期稳定高频 → 用
lfu-log-factor 50~100:压制高频 key 的涨幅,防止它们早早冲到 255 占满上限,挤掉中频 key - 默认值 10 是平衡点,只适合访问分布较均匀的场景;若观察到
INFO memory中lfu_bypassed持续偏高(说明很多 key 因 counter 太低没参与淘汰采样),就得调小 factor
为什么必须同时看 lfu-decay-time 和 lfu-log-factor
lfu-log-factor 控制“涨得多快”,lfu-decay-time 控制“跌得多快”,两者不配对调,效果会严重打折。
- 秒杀类突发流量场景,建议
lfu-log-factor 15~20+lfu-decay-time 1(单位分钟):前者抗瞬时刷屏,后者让已下架商品快速衰减,不霸占内存 - 衰减太慢(如
lfu-decay-time 30)会让过期热点长期卡在高位,掩盖新热点 - 衰减太快(如
lfu-decay-time 0.1)会导致刚热起来的 key 还没稳住就被踢出 - 验证是否真正生效:执行
CONFIG GET lfu-log-factor和CONFIG GET lfu-decay-time,必须看到你设的值,而不是默认值
验证调优效果不能只盯单个 key
OBJECT FREQ 单点值意义有限。真正有效的验证方式是看整体分布趋势。
- 用
redis-cli --scan --pattern "*"扫描一批 key,再逐个OBJECT FREQ抽样 - 统计
counter ≤ 10的占比、counter == 255的占比,对比调整前后的变化 - 如果调小 factor 后,低频 key 占比明显下降,而中频(10–100)占比上升,说明冷 key 更快被识别、中频 key 得到更好保留
- 别忽略内存开销:
allkeys-lfu比allkeys-lru多存 16bit 访问频次字段,实测内存开销高约 15%,压测时碎片率可能突然冲到 1.8+
最容易被忽略的点是:调参只是工具,业务层不配合,再好的 LFU 也白搭。Redis 不管语义,所有依赖“永不过期”的设计,必须由业务层埋逻辑过期字段,否则缓存就是内存黑洞。










