LRU 与 LFU 怎么选
两者都是内存不足时的淘汰策略:LRU 依据「最近一次访问时间」,很久没被访问的先淘汰;LFU 依据「访问频率」,并让频率随时间衰减,访问很少的先淘汰。访问模式有明显长期热点时选 LFU,能避免一次全量扫描把热点键挤出去;访问模式无规律时 LRU 更简单稳妥。
基本信息
| 策略配置 | maxmemory-policy,可选带 allkeys 与 volatile 前缀的多种策略 |
|---|---|
| 频率增长因子 | lfu-log-factor 默认 10,控制计数增长速度 |
| 频率衰减周期 | lfu-decay-time 默认 1 分钟 |
| 计数上限 | 频率计数器为 8 位,最大值 255 会饱和 |
| 查看方式 | OBJECT FREQ 看频率,OBJECT IDLETIME 看空闲时长 |
典型使用场景
- 稳定热点缓存:少量键承担大部分流量,LFU 能长期保住热点
- 防止扫描污染:偶发全量扫描不会把热点键顶掉
- 通用会话缓存:访问分布均匀时用 LRU,行为易预期
- 容量告急排查:观察淘汰计数与命中率变化判断策略是否合适
- 调参验证:调整增长因子与衰减周期后观察命中率是否改善
配置与观察
配置与观察
redis-cli CONFIG SET maxmemory-policy allkeys-lfu # 换用频率淘汰
redis-cli CONFIG GET lfu-log-factor # 默认 10
redis-cli CONFIG GET lfu-decay-time # 默认 1 分钟
redis-cli OBJECT FREQ hotkey:88 # 查看键的访问频率(LFU)
redis-cli OBJECT IDLETIME hotkey:88 # 查看空闲秒数(LRU)
redis-cli INFO stats | grep -E "evicted_keys|keyspace_hits|keyspace_misses"
redis-cli INFO memory | grep -E "maxmemory_human|used_memory_human"策略与适用
| 策略 | 淘汰依据 | 适用场景 |
|---|---|---|
| 最近最少使用 | 距上次访问的时间 | 访问分布均匀的通用缓存 |
| 最不经常使用 | 访问频率且随时间衰减 | 存在稳定热点的缓存 |
| 含过期键范围 | 只淘汰设置了过期时间的键 | 部分键需要常驻的场景 |
| 不淘汰 | 内存满时写入报错 | 数据不可丢且容量可控的场景 |
频率衰减周期设得过长:频率几乎不下降,历史热点会长期占据内存,新出现的热点很难挤进来。
淘汰策略与业务预期不一致会丢数据:上线前要明确「允许被淘汰」的键范围,必要时用只淘汰带过期时间键的策略。