volatile-lru仅淘汰带ttl的键,若大量键无过期时间则策略失效,导致内存满时报oom;需检查ttl分布、调高maxmemory-samples至10或改用allkeys-lru/allkeys-lfu。

volatile-lru 是 Redis 在内存不足时,只对设置了过期时间(TTL)的 key,按最近最少使用顺序淘汰的策略。它不碰那些没设 EXPIRE 或 SETEX 的 key,哪怕它们也很久没被访问。
这个策略看似安全,但实际容易导致内存持续打满、写入失败——尤其当你混用「长期缓存」和「短期临时数据」时。
volatile-lru 为什么经常失效?
- 它只看“设置了过期时间”的 key,如果大量 key 没设 TTL(比如用
SET直接写入),这些 key 就完全免疫淘汰,哪怕它们是冷数据; - LRU 是近似算法,默认只采样
maxmemory-samples= 5 个 key 做比较,采样数太小会导致淘汰偏差大,真正最久未用的 key 可能被跳过; - 如果业务中多数 key 都设置了长 TTL(比如 7 天),而真实访问集中在前 2 小时,
volatile-lru会误判“都算热数据”,结果一个都淘汰不掉; - 它和被动过期机制(惰性删除 + 定期删除)叠加后,可能让已过期但未被访问的 key 占着内存不放,进一步挤压可用空间。
如何选对淘汰策略并调参?
先明确你的数据特征,再匹配策略,不是所有场景都适合 volatile-lru:
-
如果你所有缓存都带 TTL,且希望保留高频访问的短期数据 → 可用
volatile-lru,但务必调高采样:maxmemory-samples 10
这能让近似 LRU 更接近真实访问序,减少误淘汰。 如果你有混合生命周期的数据(部分 key 永不过期,部分 key 短期有效)→ 改用
allkeys-lru,否则冷的永久 key 会把内存撑爆;
Redis 8.2.3下载Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
如果你发现某些 key 被反复读、其他 key 几乎不碰 →
allkeys-lfu比 LRU 更合适,它关注访问频次而非时间;如果你存的是会话、验证码等强时效数据 →
volatile-ttl更直接,优先清掉马上要过期的,避免无效堆积;如果你对数据一致性要求极高,宁可拒绝写入也不愿丢数据 → 保留
noeviction,但必须配套监控used_memory和evicted_keys指标。
maxmemory 和 maxmemory-policy 必须成对配置
单独设 maxmemory-policy volatile-lru 没用,Redis 不会自动启动淘汰,除非你同时设了 maxmemory:
-
maxmemory必须是明确字节数(如2gb)或带单位的值(100mb),不能写0或留空; - 如果用容器或云托管 Redis(如 AWS ElastiCache、阿里云 ApsaraDB),
maxmemory可能被平台限制覆盖,需确认实际生效值; - 修改后必须
CONFIG REWRITE或重启,仅CONFIG SET是临时的,进程重启即丢失。
真正难的不是选策略,而是搞清你有哪些 key、是否都设了 TTL、访问模式是偏时间局部性(LRU)还是频率局部性(LFU)。很多人调了 volatile-lru 却没查过 INFO stats 里的 evicted_keys 和 expired_keys,结果根本不知道淘汰有没有真正发生。










