Redis 内存淘汰策略 allkeys-lru 与 volatile-lru 怎么选择

文章导读
allkeys-lru 适用于纯缓存场景,所有键都可被淘汰;volatile-lru 适用于混合存储场景,只淘汰设置了过期时间的键。若业务数据不能丢失且未设置过期时间,误选 volatile-lru 会导致写入报错。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

allkeys-lru 适用于纯缓存场景,所有键都可被淘汰;volatile-lru 适用于混合存储场景,只淘汰设置了过期时间的键。若业务数据不能丢失且未设置过期时间,误选 volatile-lru 会导致写入报错。

先说结论:根据数据是否必须持久化来选择,纯缓存选 allkeys-lru,混合存储选 volatile-lru。

  • 适合:allkeys-lru 用于 Redis 仅作缓存且允许数据丢失的场景。
  • 重点看:volatile-lru 需确保业务 key 都设置了过期时间,否则无法淘汰。
  • 别忽略:默认策略 noeviction 会在内存满时拒绝写入,生产环境需显式配置。

命令速用版

查看当前淘汰策略配置,确认是否命中预期:

CONFIG GET maxmemory-policy

动态修改淘汰策略(无需重启,立即生效):

CONFIG SET maxmemory-policy allkeys-lru

永久生效需在 redis.conf 中修改 maxmemory-policy 配置项并重启服务。

为什么会这样

核心区别在于淘汰候选集不同,allkeys-lru 从所有键中挑选,volatile-lru 仅从设了过期时间的键中挑选。Redis 内存淘汰触发前提是设置了 maxmemory 限制,当写入数据导致内存达到上限后,才会执行内存淘汰逻辑。allkeys-lru 不区分 key 是否设置过期时间,整个实例所有数据都参与淘汰,适合纯缓存项目。volatile-lru 只会在设置过 expire 的缓存 key 中挑选删除,永久存储的 key 会被保护,不会被清理。

分步处理

第一步,确认业务数据性质,判断 Redis 是纯缓存还是混合存储。若 Redis 只存放固定配置、字典这类不会新增数据的静态数据,或业务缓存不允许丢失,需慎重选择淘汰策略。第二步,检查 Key 的过期时间设置情况。若选择 volatile-lru,必须确保需要被淘汰的缓存 key 都设置了过期时间,否则内存满时无法淘汰。第三步,修改配置并观察。生产环境建议先在从节点或测试环境验证,确认无写入报错后再应用到主节点。

Redis 内存淘汰策略 allkeys-lru 与 volatile-lru 怎么选择

怎么验证是否生效

使用 INFO memory 命令查看内存使用情况,关注 evicted_keys 指标。若 evicted_keys 数值随时间增长,说明淘汰策略正在工作。若内存达到 maxmemory 后写入报错且 evicted_keys 不增长,说明策略配置错误或无候选键可淘汰。同时监控客户端日志,确认是否有 OOM command not allowed 错误返回。

常见坑

volatile-lru 在没有设置过期时间的键时,等同于 noeviction 策略,内存满后写操作直接返回报错。线上生产环境禁用 allkeys-random 和 volatile-random,冷热不分,缓存命中率极低。noeviction 默认策略在做业务缓存时绝对不能用,流量高峰期新增缓存直接大量报错,接口雪崩。Redis 的 LRU 算法不是完整精准算法,内部是随机抽取少量样本 key 在样本中对比冷热做近似淘汰,性能开销极小。

常见问题

Redis 默认淘汰策略是什么?

默认策略是 noeviction,内存满了之后所有写操作直接返回报错,读命令不受影响。

allkeys-lru 和 allkeys-lfu 哪个更好?

纯缓存场景优先选 allkeys-lfu,区分冷热效果比 LRU 更好,长期运行缓存命中率更高。

设置了 volatile-lru 为什么还会报错?

可能是因为所有 key 都没有设置过期时间,导致没有候选键可淘汰,行为退化为 noeviction。

参考来源

  • Redis 数据淘汰策略
  • Redis 内存优化与淘汰策略
  • Redis 缓存替换策略:8 种淘汰策略与 LRU 实现剖析
  • Redis 内存淘汰策略详解 - 面试必备知识点
  • Redis 多种内存淘汰策略及配置技巧分享【转】