Skip to content

Redis 内存管理:过期删除与淘汰策略

这篇笔记专门整理 Redis 里和内存管理直接相关的一条主线:

  1. Key 什么时候过期
  2. 过期之后怎么删除
  3. 内存不够时应该优先淘汰谁

这部分很容易和持久化、高可用混在一起,但它们解决的问题并不相同。
更贴近这一篇重点的说法是:Redis 在运行过程中,如何管理有限内存。


1. 为什么过期删除和内存淘汰要分开理解

很多人在刚接触 Redis 时,会把这两个问题混成一句:反正数据不用了,就会被 Redis 清掉。

但它们真正处理的是两类完全不同的问题:

主题解决的问题
过期删除某个 Key 到了过期时间之后怎么办
内存淘汰当 Redis 内存不够时,应该优先丢掉哪些 Key

所以可以直接这样记:

  1. 过期删除解决的是“时间到了怎么办”
  2. 内存淘汰解决的是“内存不够怎么办”

这两个机制经常一起出现,但边界一定要分清。


2. 🌟 过期时间在解决什么问题

Redis 允许给 Key 设置 TTL,也就是生存时间。

它通常适合这些场景:

  1. 验证码
  2. 登录态
  3. 一次性令牌
  4. 缓存数据
  5. 限流窗口

过期时间的核心价值是:让短期状态自动失效,不需要业务手工清理。

但需要特别注意一点:设置了过期时间,不等于一到时间点,Redis 就会立刻把这个 Key 精准删除。

真正的删除动作,还要看 Redis 的过期删除机制。


3. 🌟 过期删除是怎么做的

3.1 惰性删除

惰性删除的意思是:

  1. 某个 Key 已经过期了
  2. Redis 不会立刻主动去删
  3. 而是在后续再次访问这个 Key
  4. 才发现它已经过期,然后顺手把它清掉

它的优点是:

  1. 节省额外扫描成本
  2. 不会为了清理过期 Key 持续消耗太多 CPU

它的缺点是:

  1. 如果某些过期 Key 长时间没人访问
  2. 它们可能还会继续占着内存

所以惰性删除更像是:访问到了才顺手清理。

3.2 定期删除

定期删除的意思是:

  1. Redis 会周期性地抽查一部分设置了过期时间的 Key
  2. 把其中已经过期的 Key 清理掉

它的优点是:

  1. 能主动回收一部分过期数据
  2. 避免所有过期 Key 都长期滞留

它的缺点是:

  1. 不可能每次都把所有过期 Key 一次清干净
  2. 需要在 CPU 开销和内存回收效率之间做平衡

所以定期删除更像是:系统定时做一轮抽样清理。

3.3 为什么 Redis 要把两者结合起来

如果只靠惰性删除,很多过期 Key 可能长期占用内存。
如果只靠定期删除,又可能让系统花太多 CPU 在清理上。

所以 Redis 的思路不是二选一,而是:

  1. 平时访问到了就惰性删除
  2. 同时再配合周期性抽样清理

这样做是在 CPU 成本和内存回收效果之间取平衡。


4. 🌟 内存淘汰在解决什么问题

内存淘汰不是因为 Key 过期,而是因为:Redis 可用内存不够了。

也就是说,即使某些 Key 还没过期,只要内存已经紧张,Redis 也必须决定:

  1. 谁应该先被淘汰
  2. 谁应该尽量保留

这就是内存淘汰策略存在的原因。

它更适合从“缓存容量控制”的角度来理解,而不是从“生命周期到点失效”的角度理解。


5. 🌟 常见内存淘汰策略怎么理解

5.1 LRU 相关

LRULeast Recently Used,可以理解成 最近最少使用

这类策略会优先淘汰最近一段时间里最少被访问到的 Key。

更适合的场景通常是:

  1. 最近访问过的数据,后续大概率还会继续访问
  2. 热点随时间波动比较明显

它的思路更偏:谁最近不热,就先淘汰谁。

5.2 LFU 相关

LFULeast Frequently Used,可以理解成 访问频率最低

这类策略会优先淘汰访问次数更少的 Key。

更适合的场景通常是:

  1. 热点长期比较稳定
  2. 某些 Key 持续高频访问,不希望因为短时间没访问就被淘汰

它的思路更偏:谁长期访问得少,就先淘汰谁。

5.3 随机淘汰

随机淘汰不按最近访问时间,也不按访问频率,而是从候选 Key 里随机挑一部分进行淘汰。

它的优点是:

  1. 实现简单

它的缺点是:

  1. 命中率通常不如 LRULFU
  2. 很可能把本来还挺有价值的数据随机丢掉

所以它更像是一个实现简单但不够精细的方案。

5.4 仅淘汰设置了过期时间的 Key

这类策略的重点是:优先从那些本来就设置了过期时间的 Key 里挑淘汰对象。

它的潜台词通常是:

  1. 某些没有过期时间的 Key 可能更重要
  2. 可以优先牺牲本就偏缓存性质的数据

这种策略适合那些把“永久 Key”和“缓存 Key”混合放在一起的场景。


6. LRULFU 怎么取舍

可以用一句话记住:

  1. LRU 更关注“最近有没有被访问”
  2. LFU 更关注“长期访问频率高不高”

如果业务热点变化很快,LRU 往往更自然。
如果业务热点长期比较稳定,LFU 往往更贴近真实访问规律。

它们没有绝对优劣,关键还是看:你的业务到底是短期热点波动大,还是长期热点稳定。


7. 这部分为什么属于内存管理,而不是持久化

这个边界很重要。

  1. 持久化关注的是:重启或故障后怎么恢复数据
  2. 内存管理关注的是:Redis 运行时怎么使用有限内存

所以:

  1. RDB / AOF 属于持久化
  2. 过期删除、TTL、淘汰策略属于内存管理

它们会相互影响,但不应该混成一类。


8. 一份实用的内存管理检查清单

可以优先检查这些问题:

  1. 这类 Key 是否真的需要设置过期时间
  2. 过期时间是否和业务生命周期匹配
  3. 是否把过期删除和内存淘汰混成了一件事
  4. 缓存容量吃紧时,淘汰策略是否符合访问模式
  5. 热点数据更适合 LRU 还是 LFU
  6. 是否把很重要的长期 Key 和纯缓存 Key 混在一起却没有区分策略

Redis 的内存管理真正难的地方,不是知道几个缩写,而是能不能把 TTL、过期删除和淘汰策略放到同一个运行视角下理解清楚。

基于 VitePress 构建的个人技术笔记。