Redis淘汰策略仅在maxmemory非0时生效,否则无论设置何种policy均不触发淘汰;noeviction超限直接报错,volatile-类只淘汰带过期时间的key,allkeys-类则全量参与;需通过CONFIG GET maxmemory与maxmemory-policy双查确认配置,并监控evicted_keys秒级增量及mem_fragmentation_ratio综合判断内存压力。

淘汰策略只对设置了maxmemory才生效
Redis 默认不启用内存淘汰,maxmemory 配置为 0(即不限制),此时无论用什么 maxmemory-policy 都不会触发淘汰。必须先设置 maxmemory,比如 CONFIG SET maxmemory 2gb,淘汰逻辑才会启动。
常见错误是只改了 maxmemory-policy 却没设 maxmemory,结果发现 evicted_keys 始终为 0 —— 不是因为策略没生效,而是压根没进入淘汰路径。
-
noeviction策略下,内存超限时直接拒绝写入,报错OOM command not allowed when used memory > 'maxmemory' -
volatile-*类策略只作用于带EXPIRE或SET ... EX seconds的 key;没设过期时间的 key 永远不会被选中 -
allkeys-*类策略无视是否过期,所有 key 都参与候选
查看当前淘汰策略用 CONFIG GET maxmemory-policy
执行 redis-cli CONFIG GET maxmemory-policy,返回形如:
1) "maxmemory-policy" 2) "volatile-lru"
注意:这个命令不校验 maxmemory 是否已启用,它只告诉你“如果要淘汰,会按什么规则来”。生产环境必须连查两步:
-
redis-cli CONFIG GET maxmemory→ 确认值不是 0 -
redis-cli CONFIG GET maxmemory-policy→ 确认策略非noeviction
配置文件里对应项是 maxmemory-policy,但线上优先用 CONFIG GET,避免重启后配置未加载或被覆盖。
淘汰统计要看 evicted_keys 增量,不是绝对值
evicted_keys 是自实例启动以来累计淘汰数,不会清零。单次查 INFO memory | grep evicted_keys 输出 evicted_keys:42 完全无法判断当前压力。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
真正有用的观察方式是盯住单位时间内的增长:
-
redis-cli --stat→ 最后一列就是每秒evicted_keys差值(需持续运行) - 脚本轮询:记录 t1 和 t2 时刻的
evicted_keys,算差值除以秒数 - 配合
used_memory_human和maxmemory比值看:若比值 >95% 且每秒淘汰数 >0,说明正在高频踢 key
特别注意:FLUSHDB、DEL 批量操作也会让 evicted_keys +1,不是所有上涨都代表内存压力 —— 要结合 expired_keys 和 keyspace_misses 趋势交叉验证。
集群环境下每个节点必须单独查
Redis 集群不聚合 evicted_keys,不同 master 节点可能配置不一致、负载不均。不能只查一个节点就认为全局正常。
排查步骤必须逐节点执行:
- 确认所有 master 的
maxmemory-policy一致(混用volatile-lru和allkeys-lfu会导致行为不可预测) - 对每个 master 运行
redis-cli -h $host -p $port INFO memory | grep -E "used_memory_human|maxmemory|evicted_keys" - 重点对比各节点的
used_memory_human/maxmemory比值和evicted_keys秒级增量
最容易被忽略的是碎片率:mem_fragmentation_ratio > 1.5 时,即使淘汰了 key,RSS 内存也难下降,压力会持续——这时光调策略没用,得考虑重启或换内存分配器。

















