Skip to Content
面试题库Redis[面试题] Redis内存满了怎么办?能说说Redis的内存淘汰策略吗?

📖 版块 A:知识讲解版 (温故知新)

  • 内存满的后果:当 Redis 使用的内存达到配置文件中设置的 maxmemory 阈值时,如果继续接收写入请求,Redis 就必须通过某种规则清理部分数据来腾出空间。这个规则就是内存淘汰策略

  • 过期删除策略 vs 内存淘汰策略(极其容易混淆):

    • 过期删除策略:针对的是那些被设置了过期时间(TTL)的 Key。当时间到了,Redis 怎么把它们删掉?(Redis 采用的是:定期删除 + 惰性删除)。

    • 内存淘汰策略:针对的是在内存不够用时,必须“杀掉”一些 Key 来保命的策略(这些 Key 可能没过期,也可能没设过期时间)。

  • Redis 的 8 种内存淘汰策略: 可以分为两个维度来记忆:淘汰范围淘汰算法

    • 淘汰范围

      • allkeys:从所有的 Key 中挑选。

      • volatile:只从设置了过期时间(TTL)的 Key 中挑选。

    • 淘汰算法

      • LRU(Least Recently Used):最近最少使用。也就是淘汰最长时间没被访问过的数据。

      • LFU(Least Frequently Used):最不经常使用(Redis 4.0 引入)。淘汰访问频率最低的数据。

      • Random:随机淘汰。

      • TTL:淘汰剩余寿命最短的数据。

    • 具体组合(8种):(这部分的内容不需要记忆,没有必要)

      • noeviction(默认):不淘汰任何数据,直接对写请求报错(OOM),保证数据不丢。

      • allkeys-lru:从所有 Key 中淘汰最久没被访问的(最常用)。

      • volatile-lru:从带 TTL 的 Key 中淘汰最久没被访问的。

      • allkeys-lfu:从所有 Key 中淘汰访问频率最低的。

      • volatile-lfu:从带 TTL 的 Key 中淘汰访问频率最低的。

      • allkeys-random:从所有 Key 中随机淘汰。

      • volatile-random:从带 TTL 的 Key 中随机淘汰。

      • volatile-ttl:从带 TTL 的 Key 中淘汰即将过期的。

🎤 版块 B:面试实战版 (高手逐字稿)

Q:如果 Redis 的内存满了会发生什么?能详细说说 Redis 的内存淘汰策略吗?

🧠 破局思路:面试官问这个,是为了考察你对 Redis 资源边界的把控能力。首先要纠正很多人把“过期删除”和“内存淘汰”混为一谈的误区。然后清晰地用“范围+算法”的维度梳理那 8 种策略,最后一定要结合实际业务场景,给出你的技术选型建议。

💬 高手逐字稿

当 Redis 使用的内存达到我们配置的 maxmemory 上限时,如果还有新的写请求进来,Redis 就会触发内存淘汰机制

首先,我需要明确一个很容易混淆的概念。很多人会把“内存淘汰策略”和“过期删除策略”搞混。过期删除(定期删除+惰性删除)是针对那些寿命到了的 Key 的正常清理;而内存淘汰是在内存告急时,为了保命而不得不强行剔除数据的应急手段。

在 Redis 中,具体淘汰谁,是由我们配置的策略决定的。一共有 8 种策略,但我通常把它们拆解成**“两个范围”乘上“三种算法”**来理解。

所谓两个范围,就是指我们是要在“所有的 Key(allkeys)”里挑,还是只在“设置了过期时间的 Key(volatile)”里挑。 所谓三种算法,分别是:

  1. LRU(最近最少使用):看谁最长时间没被碰过,谁就被淘汰。

  2. LFU(最不经常使用):这是 4.0 之后引入的,看谁被访问的频次最低,谁被淘汰。

  3. Random:纯粹的随机淘汰。 如果加上 volatile-ttl(淘汰快过期的)和默认的 noeviction(不淘汰,直接向写请求报错),就构成了 8 种策略。

在实际的生产环境中,我们应该怎么选呢?

如果是把 Redis 当作纯粹的缓存组件,也就是丢了数据也可以从 DB 里捞回来的场景,我强烈建议使用 allkeys-lru。因为它完美契合二八定律,能自动把冷数据踢掉,把热数据留在内存里。

但在有些场景下,LRU 会有一个缺陷,比如有人突然做了一次全表扫描的大数据导出,导致一堆根本不是热点的数据更新了访问时间,反而把真正的热点数据给挤了出去,这就是“缓存污染”。对于这种对缓存命中率要求极高、且经常有突发偶发流量的场景,我会配置成 allkeys-lfu。LFU 不看最后一次访问时间,只看历史访问频次,这能极大地抵抗偶发流量对缓存的污染。

最后,如果 Redis 里既存了临时缓存,又存了类似分布式锁这种绝对不能随便丢的核心业务数据,那我会选择 volatile-lru,这样 Redis 就会老老实实地只去清理那些带过期时间的缓存数据,保护核心数据不被误杀。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册