直接后果是写操作失败、服务不可用,甚至引发上游业务雪崩;OOM command not allowed when used memory > 'maxmemory'是直观表现,根本原因是maxmemory-policy为noeviction且内存达限,或策略与数据特征不匹配(如volatile-lru配无TTL键),导致淘汰失效、写入被硬拦截。

直接后果是写操作失败、服务不可用,甚至引发上游业务雪崩。 不是警告,是真实发生过的线上事故常见原因。
写入被拒绝:OOM command not allowed when used memory > 'maxmemory'
这是最直观的表现。当 maxmemory-policy 设为默认的 noeviction,且没设 maxmemory 或设得过大,Redis 会持续吃内存直到被系统 OOM Killer 杀掉;而如果设了 maxmemory 但策略仍是 noeviction,所有写命令(SET、HSET、LPUSH 等)都会立即返回这个错误。
- 读操作(
GET、HGETALL)不受影响,容易让人误判“服务还正常” - 业务层若没做写失败兜底(如降级缓存、直连 DB),就会出现数据不一致或功能缺失
- 监控上可能只看到
rejected_connections或evicted_keys为 0,却忽略total_commands_processed中大量写命令返回错误
误删关键数据:volatile-lru 配在无过期 key 的实例上
如果你给所有 key 都没设 EXPIRE,但配置了 volatile-lru,那 Redis 实际上「无键可淘汰」——它只看是否设置了过期时间,不看是否已过期。结果就是:内存持续上涨 → 触发淘汰 → 扫描一遍发现没有 volatile key → 写操作被拒绝,等效于 noeviction。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 这种配置下
evicted_keys指标恒为 0,但used_memory_peak持续逼近maxmemory - 运维排查时容易陷入“为什么没淘汰?”的误区,其实根本不是算法问题,而是范围为空
- 同理,
volatile-ttl和volatile-random在全量永久 key 场景下也完全失效
随机淘汰破坏缓存语义:allkeys-random 用在热点明显场景
LRU/LFU 是靠访问模式做决策,而 allkeys-random 完全无视 key 的热度。在电商详情页、用户会话等强热点场景下,它可能刚把高频 user:123:profile 删掉,下一秒又要把 product:456:detail 删掉。
- 缓存命中率断崖式下跌,DB 瞬间被打满
- 延迟毛刺明显,因为淘汰本身是同步阻塞操作,随机扫 key + 删除对象有开销
- 和
allkeys-lru相比,它不维护访问时间戳,省了点 CPU,但换来的稳定性代价远高于收益
LFU 计数器未预热导致“假冷数据”被误杀
allkeys-lfu 看似比 LRU 更智能,但它依赖一个衰减计数器(counter)。新 key 写入时计数器初始值很低,如果此时内存紧张,它可能在还没被访问几次就被淘汰——尤其在服务刚重启、缓存冷启动阶段。
- Redis 7.0+ 提供
lfu-log-factor和lfu-decay-time可调,但默认值对短生命周期 key 不友好 - 上线前没压测 LFU 行为,容易在流量高峰时发现“刚缓存的数据怎么老被删?”
- 相比 LRU,LFU 的内存开销略高(每个对象多存一个字节计数器),在超大实例中需留意
真正危险的不是策略本身多复杂,而是配置和实际数据特征脱节——比如用 volatile- 系列策略管理全量永久 key,或者把 noeviction 当成“安全选项”却忘了配 maxmemory。这些坑往往要等到内存真正打满那一刻才暴露。

















