Redis默认noeviction策略会在内存超maxmemory时硬性拒绝所有写命令并报OOM错误,而非自动淘汰数据;该策略生效前提必须显式配置非零maxmemory值。

CONFIG GET maxmemory-policy 返回空或报错
直接执行 CONFIG GET maxmemory-policy 却没返回值,大概率是 Redis 实例没配 maxmemory。Redis 只有在设置了内存上限后,淘汰策略才真正生效;否则即使配置了 maxmemory-policy,CONFIG GET 也可能不返回或返回空字符串。
先确认是否启用了内存限制:
- 运行
CONFIG GET maxmemory,如果返回"maxmemory" "0"或空,说明未启用淘汰机制 - 再查
INFO memory | grep used_memory,若used_memory持续增长且无上限,那当前根本不会触发任何淘汰 - 只有
maxmemory是非零值(如"2gb"),maxmemory-policy的配置才有意义
CONFIG GET maxmemory-policy 显示 noeviction 却写入失败
看到 "maxmemory-policy" "noeviction" 还是报 (error) OOM command not allowed when used memory > 'maxmemory',这不是 bug,而是预期行为——noeviction 就是“宁可拒绝写入也不删数据”。
这种情况别急着换策略,先判断是不是误判了瓶颈:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 检查
INFO memory中的mem_fragmentation_ratio:若 > 1.5,说明内存碎片高,MEMORY PURGE可能比调策略更有效 - 确认是否有大量过期 key 没被及时清理:看
expired_keys指标是否缓慢上升,若是,调高hz(比如CONFIG SET hz 25)比换volatile-ttl更治本 -
noeviction在 session 存储、幂等 token 等不可丢数据场景下反而是正确选择
redis-cli --bigkeys 和 INFO memory 都不能替代 CONFIG GET
redis-cli --bigkeys 查的是大 key 分布,INFO memory 看的是用量统计,它们都不反映当前生效的淘汰策略。唯一权威来源就是 CONFIG GET maxmemory-policy。
但要注意两个现实细节:
- 该命令返回的是当前运行时配置,不是 redis.conf 里的注释行——重启后失效的动态设置也会被它读到
- 某些云托管 Redis(如阿里云 Tair、腾讯云 CRS)可能屏蔽
CONFIG命令,此时得去控制台「参数设置」页查,或用redis-cli -a $PASS INFO | grep maxmemory-policy(部分兼容版会把策略塞进 INFO 输出) - 集群模式下,每个分片(shard)策略可能不同,需逐个
-c -p PORT连接后查
为什么 allkeys-lru 下 key 还是“凭空消失”
查出来确实是 allkeys-lru,但业务侧发现一批长 TTL 的 key 被清掉了——这不是策略失效,而是 LRU 的本质决定的:它只看访问频次/时间,不看 TTL。
典型踩坑点:
- 商品详情页缓存设了 30 天 TTL,但属于长尾流量,一周只访问一次,而新上架商品每秒访问百次 → LRU 认为旧 key “更冷”,优先淘汰
- 用
SET key value EX 2592000设 TTL,和用SET key value不设 TTL,在allkeys-lru下待遇完全一样 - 想保长 TTL 数据?要么改用
volatile-ttl(但要求所有 key 必须设 TTL),要么加一层逻辑:对关键 key 主动TOUCH延续 LRU 时间戳
maxmemory 没设,策略就形同虚设;maxmemory 设了但 maxmemory-policy 没配,Redis 会静默 fallback 到 noeviction,而不是报错提醒你**。

















