按访问频率淘汰
LFU 看的不是「多久没被访问」,而是「被访问得够不够频繁」:每个对象维护一个访问频率计数,并随时间衰减。它适合热点长期稳定、访问分布差异大的缓存场景,能缓解「偶发的一次访问就把冷键顶成热点」这类问题。
基本信息
| 策略取值 | allkeys-lfu / volatile-lfu |
|---|---|
| 原理 | 低位宽对数计数器加上随时间衰减 |
| 观测 | OBJECT FREQ 查看某键当前频率计数 |
| 适用场景 | 热点稳定、访问分化明显的缓存 |
典型使用场景
- 少数热点承担大部分流量、长尾键很多
- 批量的偶发扫描把冷键刷成「最近使用」
- 与 LRU 做对比压测,选择更贴合业务分布的策略
- 排查热点键被淘汰导致的缓存击穿
- 评估淘汰策略变更对命中率与延迟的影响
启用与观测
启用与观测
# 切换为按访问频率淘汰,注意策略变更会影响命中率
redis-cli CONFIG SET maxmemory-policy allkeys-lfu
# 查看某键当前的频率计数(只在 LFU 策略下有意义)
redis-cli OBJECT FREQ mykey
# 频率计数是概率式增长并随时间衰减,可调增益与衰减
redis-cli CONFIG GET lfu-log-factor
redis-cli CONFIG GET lfu-decay-time参数读法
| 项目 | 含义 | 注意点 |
|---|---|---|
| lfu-log-factor | 频率计数的增长快慢 | 值越大增长越慢,饱和越晚 |
| lfu-decay-time | 计数衰减的时间尺度 | 单位为分钟,决定热度半衰期 |
| OBJECT FREQ | 当前频率计数 | 只在 LFU 策略下才有意义 |
| allkeys-lfu | 所有键都参与频率淘汰 | 任何键都可能被淘汰 |
| volatile-lfu | 只淘汰设有过期时间的键 | 没有 TTL 的键不会被淘汰 |
频率计数器位宽有限,增长是对数式并且会随时间衰减,所以 OBJECT FREQ 的数字不等于访问次数;比较两个键的热度时看相对大小更有意义。
新键的初始频率很低,在热点竞争激烈的实例上容易被过早淘汰,表现为「刚写进去就被清掉」;冷启动或大促前做预热可以缓解。