真实面经题目 · 原创解析
Redis 内存满了会发生什么?
Redis 内存满了之后的行为取决于 maxmemory 和 maxmemory-policy:可能触发淘汰并继续写入,也可能拒绝会增加内存的写命令。回答时要说明触发时机、策略分类、近似算法以及对业务的影响。
真实面经题目 · 原创解析
Redis 内存满了之后的行为取决于 maxmemory 和 maxmemory-policy:可能触发淘汰并继续写入,也可能拒绝会增加内存的写命令。回答时要说明触发时机、策略分类、近似算法以及对业务的影响。
Redis 内存满了不是固定直接崩溃,而是看是否配置 maxmemory 以及淘汰策略。如果没有合理限制,进程可能继续向操作系统申请内存,最终受到系统内存、OOM 或容器限制影响。如果配置了 maxmemory,写命令执行前后 Redis 会检查内存使用,超过限制就按 maxmemory-policy 淘汰 key。策略包括 noeviction、allkeys-lru、volatile-lru、allkeys-lfu、volatile-lfu、allkeys-random、volatile-random、volatile-ttl 等。noeviction 会拒绝会增加内存的写操作,读操作通常还能执行;其他策略会尝试释放空间后继续写入。如果没有可淘汰 key,也可能返回 OOM 错误。
maxmemory 是 Redis 自身的内存上限控制,不等同于机器或容器的真实物理内存。配置后,Redis 会在可能增加内存的命令路径上检查是否超过限制,超过就进入淘汰流程或拒绝写入。若不配置上限,Redis 可能持续申请内存,最终风险转移给操作系统或容器运行时,出现交换、延迟抖动甚至进程被杀。
当策略是 noeviction 时,Redis 不主动驱逐 key。内存超过限制后,读命令、删除命令以及部分不会增加内存的操作通常仍可执行,但会增加内存的写命令会返回 OOM 类错误。这个策略适合不允许缓存自动丢数据的场景,但业务必须能处理写失败,否则会出现请求错误或状态不一致。
淘汰策略的关键差异之一是候选 key 范围。allkeys 系列可以从全部 key 中淘汰,更符合纯缓存用途;volatile 系列只从设置了过期时间的 key 中淘汰,适合把带 TTL 的数据视为可牺牲对象。如果使用 volatile 策略但很多 key 没有 TTL,内存满时可能找不到足够候选 key,最终仍然写失败。
Redis 为了控制性能成本,并不会维护严格的全局 LRU 链表或精确访问频率排名,而是基于对象上的访问时间、频率计数和随机采样做近似选择。采样数量越大,淘汰质量越接近理想结果,但 CPU 成本也会上升。面试中说“Redis 用近似 LRU/LFU”比直接说“严格淘汰最久未使用 key”更准确。
内存满会带来三类业务影响:写入失败、热点缓存被驱逐、延迟升高。写入失败需要调用方识别并降级;缓存被驱逐会增加回源压力,可能形成数据库抖动;淘汰过程本身也会消耗 CPU,尤其在大 value、频繁写入、碎片率高或候选不足时更明显。合理设置 TTL、容量、淘汰策略和监控指标是必要配套。
不一定。只有配置了会淘汰的 maxmemory-policy 时才会尝试删除 key。若策略是 noeviction,或者没有合适候选 key,Redis 会拒绝部分写命令。
如果 Redis 主要作为缓存,通常 allkeys-lru 更直接,因为所有 key 都可被淘汰。如果同一个实例里有不能丢的数据,应避免混用或使用 volatile-lru 并确保可淘汰数据都设置 TTL。
可能是没有可淘汰 key、单次写入对象太大、内存碎片明显、淘汰速度赶不上写入速度,或者策略候选范围过窄。淘汰不是无限保证写入成功,只是尽力释放空间。
过期删除会释放已经到期的 key,有助于降低内存;但内存满时触发的是淘汰流程,可以淘汰未过期 key。两者目标不同,一个按时间失效,一个按容量压力驱逐。