allkeys-lru比volatile-lru更稳,因其对所有key统一按访问热度淘汰,避免未设TTL的冷数据长期占内存导致OOM;而volatile-lru无法淘汰无过期时间的key,易触发“command not allowed”错误。

allkeys-lru 是大多数缓存场景下性能与命中率平衡最好的选择,尤其在数据访问具备局部性、且没有强时效约束时。
为什么 allkeys-lru 比 volatile-lru 更稳?
很多团队误以为“只淘汰带过期时间的 key”更安全,于是选 volatile-lru,结果线上频繁触发 OOM command not allowed when used memory > 'maxmemory' 错误。原因很直接:没设置过期时间的 key 无法被淘汰,哪怕它完全没人访问——内存卡死在那儿。
而 allkeys-lru 对所有 key 统一按访问热度筛选,只要内存满,就能稳定释放空间。它的近似 LRU 实现(采样 5 个 key 比较空闲时间)开销极低,实测延迟增加通常低于 0.1ms,远低于一次后端 DB 查询。
- 适用前提:你用 Redis 纯作缓存(不是混合存储),所有 key 都可丢
- 不适用场景:部分 key 是持久化状态(如用户配置),但又没设 TTL —— 这种情况必须补上
EX或改用volatile-lru+ 全量加过期时间 - 注意:
allkeys-lru不保证“绝对最近最少使用”,但生产环境命中率通常比随机策略高 20%~35%
volatile-ttl 看起来合理,但容易踩什么坑?
这个策略只看剩余 TTL,不看访问频次或时间。现象很典型:缓存刚预热完一批 1 小时 TTL 的数据,结果 volatile-ttl 把其中一批刚写入、还剩 59 分钟的 key 全删了,因为它们“恰好比另一批剩 60 分钟的早写入 1 秒”——本质是靠写入顺序赌运气。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 只适合 TTL 差异极大且业务明确依赖“快过期就该优先清理”的场景(如验证码、临时令牌)
- 如果所有 key TTL 都设成统一值(比如全设 3600),那
volatile-ttl退化成随机淘汰 - 监控时发现
evicted_keys增长快但keyspace_hits不升反降,大概率是它在误杀热点数据
LFU 策略真比 LRU 更适合热点数据吗?
allkeys-lfu 在 Redis 4.0+ 支持,原理是给每个 key 记访问频次并带衰减。但它对“突发流量”不友好:一个新 key 被集中刷 100 次,频次计数冲高,之后几小时都难被淘汰,哪怕它再没被访问过。
- 适合长期稳定的热点分布(如首页 Banner、固定商品池)
- 不适合活动类场景(大促期间某商品突然爆火,活动结束立刻变冷)——这时 LRU 的“时间窗口”更贴合真实访问衰减
- 启用前务必确认
lfu-log-factor和lfu-decay-time已调优,默认参数在中小流量下可能让冷热区分不明显
别忽略 maxmemory 和策略的协同效应
再好的淘汰策略也救不了乱设的内存上限。常见错误是把 maxmemory 设成机器总内存的 80%,结果系统 OOM Kill 掉 Redis 进程——Linux 内核不会管你 Redis 配了多少,只看 RSS。
- 建议值:Redis 进程独占内存 ≤ 机器总内存的 50%,预留至少 2GB 给系统和 fork(RDB/AOF)
- 验证方式:观察
used_memory_rss是否长期 >used_memory的 1.3 倍,超标说明存在内存碎片,需考虑activedefrag yes - 真正影响性能的不是策略本身,而是淘汰动作是否频繁阻塞主线程——如果
evicted_keys每秒增长 > 100,说明容量严重不足,该扩容或优化数据结构了
CONFIG SET maxmemory-policy allkeys-lru 这一行,但真正决定效果的,是你有没有把所有缓存 key 都纳入这个机制里——而不是一边用 SET 存无过期数据,一边指望 volatile-* 策略能兜底。


















