Redis 内存满了:maxmemory 与淘汰策略
发布时间:2026-01-06 12:23       
更新时间:2026-01-07 02:07
内存用到上限之后,Redis 会怎么处理新写入?答案由 maxmemory 和淘汰策略共同决定。不设上限的实例会一直吃内存,直到被操作系统以内存不足(OOM)为由杀掉;设了上限、再配上合适的淘汰策略,才能作为缓存长期稳定运行。
一、先给内存定上限
maxmemory 限制 Redis 能用的最大内存,建议设成实例可用内存的七到八成,给复制缓冲区等开销留余量。在线调整:
CONFIG SET maxmemory 4gb
查当前用量用 INFO memory,重点看 used_memory_human(实际用量)和 mem_fragmentation_ratio(内存碎片率,长期高于 1.5 说明碎片偏多)。
上限也不是越大越好:余量留得太小,主从同步和 AOF 重写的临时开销就会顶到系统层,引发交换甚至进程被杀;留得太多又白白浪费机器内存。
二、六种淘汰策略
noeviction:不淘汰,内存满了拒绝写入并报错,默认值。
allkeys-lru:全量数据里淘汰最久未访问的键,缓存场景首选。
volatile-lru:只在设了过期时间的键里淘汰,适合一部分键是持久数据、一部分是缓存的实例。
allkeys-lfu、volatile-lfu:Redis 4.0 起加入,按访问频率淘汰,适合有明显热点、偶发批量扫描的场景。
volatile-ttl:优先淘汰剩余存活时间短的键。
volatile-random、allkeys-random:随机淘汰,实际用得少。
记一个分界:带 allkeys 前缀的在全量键里挑牺牲者,带 volatile 前缀的只在设了过期时间的键里挑;实例里一个过期键都没有时,volatile 系列在内存打满时效果等同 noeviction,这一点常被忽略。
三、缓存场景怎么配
纯缓存实例直接选 allkeys-lru 或 allkeys-lfu:
CONFIG SET maxmemory-policy allkeys-lru
改完用 CONFIG GET maxmemory-policy 确认,并同步写进 redis.conf,避免重启失效。上线后如果发现缓存命中率突然下降、键被莫名清掉,先查是不是内存到线触发了大规模淘汰,而不是急着改应用。
四、一句建议
容量规划别拍脑袋:用真实数据量压一遍,测出内存水位再定 maxmemory。缓存和持久数据混用一个实例的,尽早拆成两个实例,别让淘汰策略把不该删的数据也扫掉。策略改完观察一两天命中率曲线,再决定要不要继续微调。