跳转到内容

过期与内存淘汰

用途:解释“内存打满”“缓存命中率突然下降”,并正确配置淘汰策略

Redis 采用两种组合:

  1. 惰性删除:访问 key 时才判断是否过期,过期则删除。CPU 友好,但未被访问的过期 key 长期占内存。
  2. 定期删除:后台周期任务随机抽样若干带 TTL 的 key,删除其中已过期的;若过期比例超阈值则重复。

含义:过期不等于立即释放内存。大量 key 同时到期会造成 CPU 尖峰与延迟毛刺,因此 TTL 要打散。

策略 行为 适用
noeviction 写命令报错(默认) 不允许丢数据的场景,需容量告警
allkeys-lru / allkeys-lfu 全体 key 中按最近使用/频率淘汰 通用缓存
volatile-lru / volatile-lfu 只在带 TTL 的 key 中淘汰 混合用途实例(部分数据希望常驻)
allkeys-random / volatile-random 随机淘汰 访问均匀的场景
volatile-ttl 优先淘汰剩余 TTL 最短的 想让短生命周期数据先走

注意:volatile-* 在没有可淘汰 key 时行为退化为报错。

Redis 不做精确 LRU,而是近似 LRU:每个对象记录 lru 时钟,淘汰时随机采样 maxmemory-samples(默认 5)个 key 比较,取最久未用者。采样数越大越接近 LRU,CPU 成本越高。

lfu-log-factor 与 lfu-decay-time 控制频率计数(对数递增 + 衰减),适合访问分布长尾的缓存。

  1. 设 maxmemory 为实例可用内存的合理比例(留 fork 与缓冲余量)。
  2. 监控 evicted_keys、expired_keys、used_memory vs maxmemory、碎片率;淘汰发生意味着命中率下降,要告警。
  3. 大 key 扫描(--bigkeys、MEMORY USAGE)与热 key 识别(--hotkeys、INFO commandstats、monitor 慎用)。
  4. 区分“缓存”与“存储”用途:混用会让淘汰策略互相伤害,最佳实践是拆实例。
  5. 给缓存类 key 一律设 TTL,并避免把无 TTL 的常驻数据塞满实例。
误区 修正
内存满才发现没设 maxmemory 未设时可能撑爆 OS 内存并被 OOMKill
用 volatile-lru 但所有 key 都无 TTL 无可淘汰对象,写直接失败
认为过期 key 会立刻释放 惰性 + 采样删除,内存下降有延迟
淘汰策略当容量方案 容量不足应扩容或清理,而不是靠淘汰兜底
大量 key 设同一 TTL 集中过期造成抖动与雪崩
  • Redis 官方文档:Key expiration、LRU cache、Data eviction
  • 《Redis 设计与实现》客户端与服务器部分