noeviction 是 redis 默认内存淘汰策略,但实为写入熔断开关,内存达上限时直接拒绝所有写命令而非自动淘汰数据。

noeviction 是 Redis 默认策略,但它不是“安全兜底”,而是写入熔断开关
Redis 4.0+ 版本默认 maxmemory-policy 就是 noeviction,但这个“默认”不等于“推荐”或“无感”。它意味着:只要没显式配置淘汰逻辑,内存一碰上限,所有写命令(SET、LPUSH、HSET 等)立刻返回 (error) OOM command not allowed when used memory > 'maxmemory'。这不是延迟升高,也不是后台悄悄删数据,是硬性拒绝——业务侧看到的就是“能读不能写”。
很多人误以为“默认=稳妥”,结果上线后缓存写不进、队列推失败、计数器无法更新,才去查日志发现一堆 OOM 报错。根源不在代码,而在 Redis 没被告诉“超了内存该怎么腾地方”。
改 maxmemory-policy 前必须确认三件事,否则改了也白改
直接 CONFIG SET maxmemory-policy allkeys-lru 很快,但很可能没效果。真正起作用的前提是:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 已设置
maxmemory(且值合理),仅改策略不设上限,Redis 根本不触发淘汰逻辑 - 若选
volatile-lru或volatile-ttl,必须确认你 70% 以上的 key 真设置了EXPIRE或用SETEX写入;否则“可淘汰池”为空,实际等效于noeviction - 检查
INFO memory中的evicted_keys是否在增长;为 0 说明淘汰根本没发生,要么策略没生效,要么数据特征不匹配(比如全是长 TTL 键 + volatile-* 策略)
allkeys-lru 是最省心的兜底策略,但要注意 LFU 的精度陷阱
相比 volatile-lru,allkeys-lru 不挑 key,所有键都参与 LRU 排序,适合缓存写入不可控、部分 key 无 TTL 的场景。但它不是万能解药:
-
allkeys-lfu看似更智能(按访问频次淘汰),但它的计数器受lfu-log-factor和lfu-decay-time影响;默认lfu-log-factor 10在低频访问下会导致“冷 key 被误判为热 key”,该淘汰的没淘汰 -
allkeys-random和volatile-random虽然能释放内存,但淘汰完全随机,可能刚写入的热点数据被干掉,生产环境基本不用 - 如果业务强依赖 key 的长期存在(如全局配置、权限白名单),
allkeys-*类策略有误删风险,此时应单独建库隔离,而非靠策略妥协
线上改策略必须配合监控验证,别信 CONFIG GET 返回就万事大吉
CONFIG GET maxmemory-policy 返回 allkeys-lru 只代表配置值对了,不代表淘汰真在工作。真实生效要看:
- 5 分钟内
INFO stats中的evicted_keys是否持续增长(注意:不是突增一次,是稳定爬升) -
INFO memory中used_memory_human是否在maxmemory_human附近小幅震荡,而不是一路冲顶后卡死 - 用
redis-cli --stat观察实时内存变化,同时抓包或打日志确认业务写入错误是否消失
最容易被忽略的是 client-output-buffer 占用——主从同步卡住时,slave 缓冲区可能吃掉几百 MB,这部分不计入 used_memory,但会挤占真实可用内存。所以 mem_fragmentation_ratio > 1.5 或 redis-cli memory doctor 提示 “client output buffer is full”,就得先处理同步问题,再调策略。










