Skip to content

Redis 使用的过期删除策略是什么?

Redis 过期删除策略

Redis 的过期删除策略用于清理设置了过期时间(TTL)的键,主要包括: 1. 惰性删除(Lazy Deletion): - 访问键时检查是否过期,若过期则删除。 2. 定期删除(Periodic Deletion): - 定时采样检查部分键,删除过期键。

综合策略

  • 惰性 + 定期:Redis 结合两者,既保证内存及时释放,又避免频繁扫描的性能开销。

核心点

  • 不主动全量删除,平衡效率和内存使用。

1. 策略详解

(1) 惰性删除(Lazy Deletion)

  • 原理
  • 每次访问键(如 GETSET)时,检查其过期时间(TTL)。
  • 若已过期,删除键并返回 nil
  • 实现
  • Redis 在 dict(哈希表)中存储键的过期时间戳。
  • 操作时调用 expireIfNeeded 检查。
  • 优点
  • 按需删除,节省 CPU。
  • 缺点
  • 未访问的过期键占用内存。
  • 示例
SET key value EX 10  # 设置 10 秒过期
# 10 秒后
GET key              # 检查并删除,返回 nil

(2) 定期删除(Periodic Deletion)

  • 原理
  • Redis 后台线程定时(默认每秒 10 次)随机采样部分键,检查并删除过期键。
  • 实现
  • 函数 activeExpireCycle
    1. 从数据库随机取样(如 20 个键)。
    2. 检查 TTL,删除过期键。
    3. 若过期比例高,循环执行。
  • 参数
  • hz:控制采样频率,默认 10(每秒 10 次)。
  • 优点
  • 主动清理,减少内存浪费。
  • 缺点
  • 随机采样,可能漏删。
  • 高负载下不彻底。
  • 示例
  • 过期键未被访问,定期任务清理。

(3) 综合机制

  • 惰性删除:处理访问时的过期键。
  • 定期删除:清理未访问的过期键。
  • 结果
  • 内存不会无限增长,但可能短暂残留过期键。

2. 为什么不用主动删除

  • 全量定时删除
  • 遍历所有键,CPU 开销大。
  • 高并发下影响性能。
  • Redis 选择
  • 惰性 + 定期,兼顾性能和内存。

3. 内存淘汰策略(补充)

  • 与过期删除区别
  • 过期删除针对设置了 TTL 的键。
  • 内存淘汰针对内存不足时的所有键。
  • 策略maxmemory-policy):
  • volatile-lru:从过期键中按 LRU 删除。
  • allkeys-lru:所有键按 LRU 删除。
  • noeviction:不淘汰,报错。
  • 配置
maxmemory 100mb
maxmemory-policy volatile-lru

4. 源码与实现

  • 键结构
  • redisDbexpires 字典存储键和过期时间。
  • 检查逻辑
int expireIfNeeded(redisDb *db, robj *key) {
    if (!keyIsExpired(db, key)) return 0;
    deleteKey(db, key); // 删除过期键
    return 1;
}
  • 定期任务
  • serverCron 调用 activeExpireCycle

5. 延伸与面试角度

  • 与 TTL
  • EXPIRE key seconds 设置过期。
  • TTL key 查看剩余时间。
  • 局限
  • 高并发下定期删除不及时。
  • 需配合内存淘汰。
  • 实际应用
  • 缓存:过期自动失效。
  • 会话:定期清理。
  • 面试点
  • 问“策略”时,提惰性和定期。
  • 问“优化”时,提 hz 调整。

总结

Redis 使用惰性删除(访问时检查)和定期删除(定时采样)组合清理过期键,高效平衡性能和内存。面试时,可提实现原理或举缓存示例,展示理解深度。