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 都设置了过期时间,否则内存满时无法淘汰。第三步,修改配置并观察。生产环境建议先在从节点或测试环境验证,确认无写入报错后再应用到主节点。
怎么验证是否生效
使用 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 多种内存淘汰策略及配置技巧分享【转】