### [Redis 内存满了怎么办?你有想过吗?](https://www.isearch.life/article/507) **Published:** 2026-04-10T08:09:33 **Author:** tearell **Excerpt:** 面试考察点 基础掌握度:面试官不仅仅是想知道 Redis 有过期策略,更是想知道你是否清楚 Redis 采用的是 惰性删除 + 定期删除 的组合方案,而不是定时删除,以及为什么要这样设计。 原理理解深度:考察你是否了解过期字典的内部结构,定 ## 面试考察点 1. **基础掌握度**:面试官不仅仅是想知道 Redis 有过期策略,更是想知道你是否清楚 Redis 采用的是 **惰性删除 + 定期删除** 的组合方案,而不是定时删除,以及为什么要这样设计。 2. **原理理解深度**:考察你是否了解过期字典的内部结构,定期删除的采样逻辑(随机抽取、循环检测),以及这些设计背后的性能与内存权衡。 3. **知识关联能力**:能否自然过渡到 “过期策略解决不了内存问题时怎么办” → 内存淘汰策略(`maxmemory-policy`),展示完整的知识体系。 ## 核心答案 Redis 采用 **惰性删除 + 定期删除** 两种策略配合使用: | 策略 | 触发时机 | 行为 | 特点 | | --- | --- | --- | --- | | **惰性删除** | 访问 Key 时 | 发现过期才删除 | 对 CPU 友好,但可能有垃圾数据残留 | | **定期删除** | 每隔一段时间 | 随机抽查一批 Key,删除过期的 | 折中方案,平衡 CPU 和内存 | **一句话结论**:Redis **不使用定时删除**(到期立即删),因为那会消耗大量 CPU 资源。而是用 “惰性 + 定期” 的组合策略,在 CPU 和内存之间取一个平衡。如果过期策略清理不过来,内存还是满了,就会触发 **内存淘汰策略**。 ## 深度解析 ### 一、三种过期策略的理论对比 在讲 Redis 的方案之前,先了解一下理论上过期策略有三种: ![](https://www.isearch.life/resources/2026/04/redis%E8%BF%87%E6%9C%9F1.png) 上图展示了三种过期策略的理论对比: - **定时删除**:每个 Key 设置一个定时器,到期立即删除。内存最优,但 CPU 开销太大,Redis **没有采用**。 - **惰性删除**:只在访问时检查。CPU 最友好,但过期不访问的 Key 会一直占内存,Redis **采用**。 - **定期删除**:每隔一段时间抽查。是 CPU 和内存的折中方案,Redis **采用**。 Redis 选择 **惰性 + 定期** 的组合策略,既不会消耗过多 CPU,又能及时清理大部分过期数据。 ### 二、过期字典:Redis 如何记录 Key 的过期时间? ![](https://www.isearch.life/resources/2026/04/redis%E8%BF%87%E6%9C%9F2.png) 上图展示了 Redis 存储过期时间的内部结构: - Redis 在每个数据库(`redisDb`)中维护了两个字典:\*\*`dict`\*\*(主字典,存储所有 Key-Value 数据)和 \*\*`expires`\*\*(过期字典,存储设置了过期时间的 Key 及其过期时间戳)。 - 过期字典的 key 指向主字典中的同一个 Key 对象(不是副本),所以不会额外占用太多内存。 - 当检查一个 Key 是否过期时,只需在 `expires` 字典中查找对应的时间戳,与当前时间比较即可。 ### 三、惰性删除的工作流程 ![](https://www.isearch.life/resources/2026/04/redis%E8%BF%87%E6%9C%9F3.png) 上图展示了惰性删除的判断流程: - **核心思路**:每次访问 Key 时,顺便检查一下是否过期。如果过期了,就删除并返回空;没过期就正常返回数据。 - **优点**:对 CPU 极度友好,只有在业务需要访问时才执行删除操作,不会浪费 CPU 资源。 - **缺点**:如果有些 Key 过期了但 **一直没有被访问**,它们就会一直占用内存,成为 “垃圾数据”。 ### 四、定期删除的工作流程 定期删除是 Redis 主动清理过期数据的机制,它的执行逻辑比惰性删除复杂得多。 ![](https://www.isearch.life/resources/2026/04/redis%E8%BF%87%E6%9C%9F4.png) 上图展示了定期删除的完整流程,核心逻辑: - **随机抽取**:每 100ms 从过期字典中随机抽取 20 个 Key,检查是否过期。 - **自适应循环**:如果这 20 个 Key 中过期的比例超过 25%,说明当前过期 Key 很多,就再随机抽 20 个继续清理,直到过期比例降到 25% 以下,或者执行时间超过上限(默认 25ms)。 - **为什么限制 25ms**:定期删除是在 Redis 主线程中执行的,如果清理时间过长会阻塞正常请求,所以必须严格限制单次执行时长。 **定期删除的局限性**: - 由于是 **随机抽样**,总会有一些过期 Key 被遗漏,不会全扫一遍。 - 如果过期 Key 数量非常多,而随机抽取的概率有限,仍然会有大量过期 Key 残留在内存中。 ### 五、过期策略 + 内存淘汰策略 = 完整方案 “惰性 + 定期” 只能清理 **过期了的 Key**。如果有些 Key 没有设置过期时间,或者过期策略清理速度跟不上新 Key 的写入速度,内存还是会满。这时就需要 **内存淘汰策略** 出场了。 ``` # redis.conf 配置最大内存和淘汰策略 maxmemory 4gb maxmemory-policy allkeys-lru ``` **Redis 8 种内存淘汰策略**: | 策略 | 行为 | 适用场景 | | --- | --- | --- | | `noeviction` | 不淘汰,写入直接报错(**默认**) | 数据不能丢失 | | `allkeys-lru` | 从所有 Key 中淘汰最久未使用的 | **通用缓存(推荐)** | | `allkeys-lfu` | 从所有 Key 中淘汰使用频率最低的(Redis 4.0+) | 热点数据明显的缓存 | | `allkeys-random` | 从所有 Key 中随机淘汰 | 无访问热点 | | `volatile-lru` | 从设置了过期的 Key 中淘汰最久未使用的 | 混合使用(部分持久化) | | `volatile-lfu` | 从设置了过期的 Key 中淘汰使用频率最低的 | 混合使用 | | `volatile-random` | 从设置了过期的 Key 中随机淘汰 | 混合使用 | | `volatile-ttl` | 从设置了过期的 Key 中淘汰剩余时间最短的 | 业务有明确 TTL 需求 | **生产环境推荐**:`allkeys-lru`(通用缓存)或 `allkeys-lfu`(热点明显的缓存)。 ## 面试高频追问 1. **追问一:为什么 Redis 不用定时删除?** 定时删除需要为每个设置了过期时间的 Key 维护一个定时器,如果同时有几十万个 Key 设置了过期时间,就会有几十万个定时器同时运行,**严重消耗 CPU 资源**,影响 Redis 处理正常请求的性能。Redis 作为高性能缓存,把 CPU 留给业务处理更重要。 2. **追问二:LRU 和 LFU 淘汰策略的区别?** - **LRU(Least Recently Used)**:淘汰最久没被访问的 Key,基于 “最近访问的数据大概率还会被访问” 的假设。Redis 的 LRU 是近似算法,随机采样 N 个 Key(默认 5 个),淘汰其中最久未访问的。 - **LFU(Least Frequently Used)**:淘汰访问频率最低的 Key,基于 “访问频率高的数据更有价值” 的假设。Redis 4.0 引入,更适合 **热点数据明显** 的场景(比如 20% 的数据占 80% 的访问量)。 3. **追问三:如何查看 Redis 当前内存使用情况?** ``` # 查看内存使用详情 INFO memory # 关键指标: # used_memory:已用内存 # maxmemory:最大内存限制 # maxmemory_policy:当前淘汰策略 ``` ## 常见面试变体 - 变体一:”Redis 的 Key 过期了是怎么被删除的?” - 变体二:”Redis 过期策略和内存淘汰策略的区别?” - 变体三:”Redis 内存满了怎么办?” - 变体四:”Redis 的 LRU 算法了解吗?是精确的还是近似的?” ## 记忆口诀 **过期策略**:惰性删除(访问才删)+ 定期删除(随机抽查,过期超 25% 继续抽)。 **为什么不单独用一种**:惰性删不干净(残留垃圾),定期删不精确(随机抽样),两者互补。 **内存满了**:过期策略搞不定 → 内存淘汰策略接手 → `allkeys-lru` 最常用。 ## 总结 Redis 过期策略采用 **惰性删除 + 定期删除** 的组合方案。惰性删除在访问时才检查并删除过期 Key,对 CPU 友好;定期删除每 100ms 随机抽样一批 Key 清理过期的,防止大量过期数据残留。两者互补,在 CPU 和内存之间取得平衡。如果过期策略仍无法释放足够内存,就会触发 **内存淘汰策略**(推荐 `allkeys-lru` 或 `allkeys-lfu`)。 **Categories:** 热门资讯 ---