allkeys-lru是纯缓存场景下最稳妥的默认选择;它对所有key按访问时间近似淘汰,适配二八规律,但实际为采样近似LRU,默认抽查5个key,非精确实现。

allkeys-lru 是缓存场景下最稳妥的默认选择
纯缓存场景(所有 key 都可丢、无持久化语义)下,allkeys-lru 是生产环境最常用且风险最低的策略。它不依赖过期时间设置,对所有 key 统一按访问时间排序淘汰,天然适配“二八访问规律”——最近频繁访问的数据大概率还会被访问。
容易踩的坑:
- 误以为
allkeys-lru是精确 LRU:Redis 实际用的是采样近似算法,默认只抽查maxmemory-samples个 key(默认值为 5),再从中挑最久未访问的淘汰。这意味着冷热区分不如理论 LRU 严格,但换来了 O(1) 时间复杂度和极低内存开销 - 没调大
maxmemory-samples却期望强局部性:如果业务冷热极其分明(比如电商大促期间 TOP100 商品占 90% 流量),可适当调高该值(如设为 10),但注意 CPU 开销会线性上升 - 混用
volatile-*策略却忘了给 key 设EXPIRE:比如选了volatile-lru,但大量缓存 key 没设置过期时间,那它们永远不会被选中淘汰,最终触发noeviction行为(写失败)
什么时候该换用 allkeys-lfu?
allkeys-lfu 更适合访问模式呈现“长尾+强热点”的场景:某些 key 被高频反复访问(如首页 banner、用户登录态),而其他 key 访问稀疏但周期性存在(如用户历史订单页)。LFU 通过衰减计数器跟踪长期热度,比 LRU 更能保留这类稳定热点。
但要注意:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- LFU 的计数器有衰减机制(默认每分钟衰减一次),旧访问记录不会永久影响淘汰决策,这点比朴素计数更合理
- LFU 比 LRU 多维护一个访问频次字段,内存占用略高;首次启用时需等热度积累,冷启动阶段淘汰行为可能不如 LRU 稳定
- 如果业务里根本没有明显热点(比如日志类缓存、临时计算结果),
allkeys-lfu和allkeys-lru效果差异不大,没必要切换
volatile-* 策略只在混合存储场景下有意义
当 Redis 同时承担缓存 + 少量持久化数据角色时(例如用 Redis 存 session + 存配置白名单),才需要 volatile-lru 或 volatile-lfu。它的核心约束是:没设 EXPIRE 的 key 永远不参与淘汰。
常见误用:
- 以为 “volatile” 表示“易失”,自动覆盖所有缓存 key:错。必须显式调用
EXPIRE或SETEX才算 volatile key - 用
volatile-ttl替代业务过期逻辑:这个策略只看剩余 TTL,不关心访问热度。如果大量 key 设置了相同 TTL(比如统一 30 分钟),它就退化成随机淘汰,命中率不可控 - 在纯缓存集群里配
volatile-lru却漏设过期时间:等于开了个空策略,内存满后直接报错
noeviction 不是“安全选项”,而是故障信号
noeviction 是 Redis 默认策略,但它在缓存场景下等于主动拒绝服务——一旦内存触顶,所有写命令(SET、HSET、LPUSH 等)立即返回 (error) OOM command not allowed when used memory > 'maxmemory'.。这不是优雅降级,而是把压力甩给上游应用。
真正需要关注的是:谁在持续写入却没配淘汰策略? 这往往暴露了两类问题:一是缓存 key 没设过期时间(比如用 SET 代替 SETEX),二是业务误把 Redis 当持久化存储用(比如存用户原始日志)。这两类问题不解决,换任何淘汰策略都只是掩盖症状。

















