Skip to content

过期与内存淘汰

惰性删除与定期删除、8 种淘汰策略、LRU 与 LFU、maxmemory。

Updated View as Markdown
For humans

过期与内存淘汰

两个容易混的概念:过期是把到期的 key 删掉(TTL 到了),淘汰是内存满了挑 key 腾空间。一个管生命周期,一个管容量上限。

过期删除策略

Redis 用惰性删除 + 定期删除组合:

策略 机制 问题
惰性删除 访问 key 时才检查是否过期,过期就删 过期但没人访问的 key 一直占内存
定期删除 每秒 10 次,随机采样一批 key 检查过期 采样不全面,仍可能有残留
惰性 + 定期 组合兜底 大量过期 key 时内存压力仍在,等淘汰兜底

组合效果:过期 key 不会立刻消失,但也不会无限堆积。生产上大量 key 同时过期(缓存雪崩的诱因之一)要靠 TTL 加随机值打散。

内存淘汰:8 种策略

maxmemory 设置内存上限,超限后按 maxmemory-policy 淘汰:

策略 范围 行为
noeviction(默认) 全部 不淘汰,写命令直接报错
allkeys-lru 全部 key 淘汰最久未访问
volatile-lru 只限设了 TTL 的 同上,范围收窄
allkeys-lfu 全部 key 淘汰访问频率最低
volatile-lfu 只限设了 TTL 的 同上
allkeys-random 全部 key 随机淘汰
volatile-random 只限设了 TTL 的 随机淘汰
volatile-ttl 只限设了 TTL 的 淘汰剩余 TTL 最短的

记忆口诀:8 种 = noeviction(不淘汰)+ 3 种算法(lru/lfu/random)乘 2 个范围(allkeys/volatile)+ volatile-ttl(淘汰 TTL 最短)。volatile 系要求 key 都设 TTL,缓存场景常用 allkeys-lru 或 allkeys-lfu。

LRU 与 LFU

Redis 的 LRU 是近似 LRU:不维护精确访问时间链表,而是采样(默认 5 个 key)淘汰最旧的,兼顾性能。maxmemory-samples 调大更精确但更慢。

  • LRU:淘汰最久未使用。缺陷:一次批量访问让冷 key 变“热”,之后不再访问却占着位置
  • LFU(4.0+):淘汰访问频率最低。用计数器衰减模拟时间流逝,抗“一次性热点”更好

选型:读多写少的稳定业务用 LRU;有突发热点或访问模式随时间变化的用 LFU。

面试追问

  1. 过期和淘汰的区别? 过期是 TTL 到了删 key;淘汰是内存满时按策略腾空间。淘汰可能删掉没过期的 key
  2. 惰性删除的问题? 过期不访问的 key 一直占内存,所以配定期删除兜底
  3. 8 种淘汰策略怎么记? 算法(lru/lfu/random/ttl)乘范围(allkeys/volatile),加 noeviction
  4. Redis 的 LRU 是精确的吗? 不是,近似 LRU,采样 5 个淘汰最旧。精确 LRU 维护成本高
  5. 什么场景用 LFU? 访问频率比新鲜度更重要的场景,防一次性热点。Redis 4.0+ 支持
Navigation

Type to search…

↑↓ navigate↵ selectEsc close