Redis 的过期删除机制和内存淘汰策略


一、Redis 过期删除机制(Expiration)

Redis 支持为每个 key 设置 TTL(Time To Live,生存时间),时间一到,key 会被删除。但是,过期不等于马上删除,删除的时机和方式由 Redis 控制,主要分为以下三种机制:

1️⃣ 惰性删除(Lazy Deletion)

  • 触发时机:只有当客户端访问该 key(如 GET/SET)时,Redis 才会检查这个 key 是否过期。
  • 如果已过期,则删除并返回 nil。
  • 特点:
    • 不占用太多 CPU。
    • 如果某些过期的 key 长时间不访问,可能会堆积,占用内存。

2️⃣ 定期删除(Active Expiration)

  • Redis 内部会启动定时任务(默认每秒 10 次)。
  • 随机抽取部分带有过期时间的 key 进行检查和删除。
  • 如果删除的比例过高,说明可能有大量过期数据,Redis 会加快检查节奏,直到 CPU 时间片耗尽或检查量达标。
  • 优点:防止大量过期 key 堆积,占用内存。

3️⃣ 内存不足时强制删除(和内存淘汰策略有关)

  • 如果内存达到上限,Redis 会触发内存淘汰机制(后面细说)。
  • 此时会优先清理掉已过期的数据。

二、内存淘汰机制(Eviction Policy)

当 Redis 达到配置的内存最大值(maxmemory)时,如果继续写入数据,Redis 会根据设置的淘汰策略决定如何处理。核心原则:优先删除不重要的数据,保证系统可用

Redis 支持的淘汰策略(maxmemory-policy):

策略 描述
noeviction(默认) 不删除任何数据,写操作会直接返回错误。适合纯缓存场景以外的严肃业务
volatile-lru 只对设置了过期时间(TTL)的 key 使用 LRU 算法淘汰
allkeys-lru 所有 key 中使用 LRU 淘汰
volatile-random 随机淘汰设置了 TTL 的 key
allkeys-random 随机淘汰所有 key
volatile-ttl 优先淘汰即将过期的 key(TTL 小的先被淘汰)
allkeys-lfu 基于访问频率(LFU)淘汰所有 key(Redis 4.0+)
volatile-lfu 基于访问频率淘汰带 TTL 的 key(Redis 4.0+)

重点策略解读:

  • LRU(Least Recently Used):最近最少使用,适合热点数据明显的场景。
  • LFU(Least Frequently Used):淘汰最不常访问的,适合长期稳定的热数据。
  • TTL淘汰(volatile-ttl):针对有时效性的业务场景,比如限流、验证码。

三、Redis 过期删除与内存淘汰的关系

对比项 过期删除机制 内存淘汰策略
触发条件 key 达到过期时间 Redis 内存达到 maxmemory 限制
主动性 主动(定期任务)+ 被动(访问时检查) 只有达到内存上限才触发
清理范围 只清理设置了 TTL 的 key 根据策略决定清理范围(可全局或 TTL 内)
影响 防止内存被过期数据撑爆 保证系统可用,避免 OOM(内存溢出)

四、最佳实践

✅ 设置合理的 maxmemory,避免 Redis 被打爆。
✅ 缓存型业务推荐 allkeys-lru,保证热点数据常驻内存。
✅ 高频限流或验证码场景可用 volatile-ttl,优先清理快过期的数据。
✅ 持久化业务(AOF/RDB)慎用淘汰,防止数据丢失。
✅ 监控 used_memoryevicted_keys,及时发现内存压力。


五、常用配置示例(redis.conf)

maxmemory 2gb
maxmemory-policy allkeys-lru

查看当前策略:

127.0.0.1:6379> CONFIG GET maxmemory-policy

✅ 总结一句话

过期删除是为了让“该死的数据死掉”,内存淘汰是为了防止“所有数据一起拖垮系统”。两者配合,保证 Redis 既轻盈又高效。

你可能感兴趣的:(redis,缓存)