Redis过期策略

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis作为高性能内存数据库,支持为键设置TTL(生存时间),过期策略就是用于自动清理过期键、释放内存的核心机制。其核心设计目标是平衡CPU资源消耗内存利用率,避免无效键长期占用内存,同时保障Redis核心读写性能不受影响。

一、Redis过期键底层存储:过期字典

Redis不会随机扫描所有键查找过期数据,而是专门维护一个过期字典(expires),该字典是全局哈希表,存储结构清晰高效:

  • 键:指向Redis数据库中对应键的指针,复用原有键空间,避免重复存储
  • 值:键的绝对过期时间戳(毫秒级),用于快速判断键是否过期

所有设置了EXPIRE、PEXPIRE、SETEX等过期指令的键,都会被自动加入过期字典;删除键时也会同步清理过期字典中的映射关系,查询、删除操作的时间复杂度均为O(1),这是Redis过期策略高效运行的基础。

二、三大基础过期删除策略

业界通用的过期删除方案有三种,各自侧重不同,优缺点鲜明,Redis并未单一采用,而是择优组合使用。

1. 定时删除策略

核心逻辑:为每个设置过期时间的键创建独立定时器,到期后立即触发删除操作,实现“到期即删”。

  • 优点:清理时效性拉满,过期键不会占用内存,数据准确性最高,不存在“过期键仍可访问”的情况
  • 缺点:CPU开销极大,大量过期键会触发密集定时器事件,抢占主线程读写资源,导致Redis响应变慢、吞吐量下降

该策略对内存友好但对CPU极不友好,Redis仅在极端场景下少量使用,不会作为核心方案。

2. 惰性删除策略

核心逻辑:不主动扫描清理过期键,仅在客户端访问键时,先检查该键是否存在于过期字典且已过期,再决定是否删除。

  • 执行流程:客户端发起GET/SET等命令→Redis查询过期字典→判断时间戳是否过期→过期则删除键并返回nil,未过期则正常返回数据
  • 优点:CPU资源占用极低,仅在键被访问时执行删除操作,不影响主线程核心读写
  • 缺点:内存浪费严重,长期未被访问的过期键会一直滞留内存,形成“内存垃圾”,极端情况下会导致内存溢出

这是Redis的基础过期策略,兼顾CPU性能,但无法单独解决内存积压问题。

3. 定期删除策略

核心逻辑:每隔固定时间,Redis主动抽取部分过期字典中的键进行检查,删除已过期的键,通过分批抽查平衡CPU和内存压力。

  • 优点:可控性强,通过限制单次清理时长和抽查数量,避免CPU占用过高;能主动清理大部分闲置过期键,缓解内存压力
  • 缺点:属于概率性清理,无法保证所有过期键都被抽查到,仍有少量过期键可能滞留内存;抽查频率和数量设置不当,会出现清理不及时或CPU飙高问题

三、Redis官方默认组合过期策略

Redis摒弃了单一策略的弊端,采用惰性删除+定期删除的组合方案,既保障CPU性能,又尽可能清理过期键,是兼顾效率和内存的最优解。

1. 惰性删除:兜底校验

作为第一道防线,所有键的访问操作都会触发过期校验,确保被访问的过期键绝对不会被返回,杜绝业务读取到过期数据的问题,保证数据一致性。

2. 定期删除:主动清理

Redis默认每秒执行10次定期清理(每100ms一次,可通过hz配置调整),执行流程严格受控:

  1. 随机抽取过期字典中20个键进行过期校验
  2. 删除其中已过期的键,统计过期键占比
  3. 若过期键占比超过25%,重复执行抽取+删除操作,直到占比低于25%或单次清理耗时达到上限(默认25ms)

这种设计既保证了过期键清理效率,又严格限制了CPU占用,不会阻塞主线程的正常读写请求。

核心特点:组合策略无法做到100%实时清理所有过期键,未被抽查、也未被访问的过期键仍会短暂占用内存,需配合内存淘汰机制做最终兜底。

四、兜底方案:Redis内存淘汰机制

当Redis内存使用达到maxmemory配置阈值时,即使键未过期,也会触发内存淘汰,彻底解决内存溢出风险,这是过期策略的补充机制,二者分工明确:

  • 过期策略:针对已设置TTL的过期键,主动/被动清理
  • 内存淘汰:针对所有键(含未过期键),内存不足时强制清理

Redis提供8种淘汰策略,核心分为两大类:

1. 仅针对过期键(volatile系列)

  • volatile-lru:删除最近最少使用的过期键
  • volatile-lfu:删除使用频率最低的过期键
  • volatile-random:随机删除过期键
  • volatile-ttl:删除即将过期的键

2. 针对所有键(allkeys系列)

  • allkeys-lru:删除最近最少使用的键(生产环境最常用)
  • allkeys-lfu:删除使用频率最低的键
  • allkeys-random:随机删除键
  • noeviction:不删除任何键,直接拒绝写入(默认策略)

五、实战配置与避坑要点

  1. hz参数调优:默认hz=10(每秒10次定期清理),高内存场景可适当调大(如15-20),但不宜过高,避免CPU占用超标
  2. 避免大批量键同时过期:集中过期会导致定期删除压力骤增,可能引发短暂阻塞,建议给键设置随机偏移的过期时间
  3. 合理配置maxmemory-policy:缓存场景优先选allkeys-lru,持久化场景慎用淘汰策略,避免数据丢失
  4. 监控内存指标:关注过期键数量、内存使用率,及时发现清理不及时的问题

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis基础 文章被收录于专栏

本专栏带你从零掌握 Redis 核心知识,清晰讲解过期策略、内存淘汰等面试重点。用通俗语言拆解底层原理,搭配实战案例与常见问题总结,兼顾入门理解与面试备考,帮你快速建立完整 Redis 知识体系,轻松应对开发与面试

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 10:38
实力求职者:真的绷不住了,第一张霸总人设,第二张求生欲拉满
点赞 评论 收藏
分享
昨天 10:36
云南大学 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务