Redis过期删除策略

物理存储:expires 字典

当你为一个 Key 设置了过期时间(如 EXPIRE key 3600),Redis 内部并不会修改该 Key 的原有结构,而是将其放入一个专属的过期字典中。

  • 数据结构 :在每个 Redis 数据库(redisDb)中,都有一个名为 expires 的 dict(字典)。
  • Key :指向原始数据库 dict 中同一个 SDS 对象的指针(为了省内存,这里不会复制字符串)。
  • Value :一个 long long 类型的整数,存储的是该 Key 的绝对过期时间戳(毫秒级 Unix 时间戳)。
  • 注意:过期字典存储的不是已经过期的数据,而是设置了过期时间的数据

3种常见过期删除策略

1. 定时删除 (Scheduled / Timed Deletion)

  • 物理动作 :在设置 Key 过期的同时,创建一个定时器(Timer)。当时间一到,定时器立即触发回调函数,物理抹除该数据。
  • CPU 影响 :极高。想象一下如果有 100 万个 Key 同时过期,Redis 就得瞬间启动 100 万个回调。在 Redis 这种单线程模型里,这会直接把主线程卡死,导致无法处理正常的读写请求。
  • 内存影响 :极低。一旦过期立刻释放,内存利用率最高。
  • 现状 :Redis 并没有采用这种策略。因为它对 CPU 太不友好了,完全违背了高性能缓存的初衷。

2. 惰性删除 (Lazy Deletion)

  • 物理动作 :Redis 从不主动检查 Key 是否过期。只有当你执行 GET、SET 等命令触碰到某个 Key 时,Redis 才会"顺便"检查它的过期字典。
  • 判断逻辑 :如果发现已过期,原地处决(删除),并返回 nil;如果没过期,正常返回数据。
  • CPU 影响 :极低。它把删除的压力摊销到了每一次业务请求中,没有额外的扫描开销。
  • 内存影响 :有风险 。如果大量 Key 过期后从此再无人问津(冷数据),它们会一直霸占物理内存,造成严重的内存泄漏。

3. 定期删除 (Periodic Deletion)

  • 物理动作 :Redis 内部的 serverCron 任务会每秒执行 10 次(默认频率),调用 activeExpireCycle 函数对 expires 字典进行随机抽样检查。
  • 算法逻辑 (25% 准则) :
    1. 从过期字典中随机抽取 20 个 Key。
    2. 删除其中已过期的 Key。
    3. 循环触发 :如果这 20 个 Key 中过期的比例超过 25%,说明过期 Key 还是很密集,立即再次执行步骤 1。
    4. 熔断机制:为了防止扫描太久导致主线程卡顿,单次扫描有严格的时间上限(通常是 25ms)。
  • 物理权衡:通过限制删除操作执行的时长和频率,来减少对 CPU 的占用,同时又能有效释放内存。

💡

Redis 的物理方案 = 惰性删除 + 定期删除

这是一个互补的闭环:

  • 定期删除 负责在大规模数据中进行"地毯式巡逻",消灭大部分过期的冷数据。
  • 惰性删除 负责作为"临检岗",拦截那些漏网之鱼,保证用户绝对不会读到过期的数据。

相关推荐
其实防守也摸鱼5 分钟前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
吹什么轩32 分钟前
MySQL:数据库基础
数据库·mysql
内存漫游33 分钟前
Undo、Redo 与事务回滚
数据库
FluxDB39 分钟前
用 Rust + GPUI 重做数据库客户端
数据库·mysql
烬羽1 小时前
PostgreSQL:AI 时代原生的"隐型"向量数据库 — 用 pgvector 给消息表加上长期记忆
数据库·人工智能·程序员
Yyyyyy~1 小时前
【Mysql】增删查改操作
数据库·mysql
钱栈up2 小时前
前端改了三页、后端也动了,用户说「完全没变化」——我在 116 库上找到的三个真凶
css·数据库
这个DBA有点耶2 小时前
索引建了查询却更慢——优化器选错索引与Index Merge的隐藏代价
数据库·架构·代码规范
云贝贝贝2 小时前
删了却没变小:PostgreSQL 死元组与表膨胀排查
数据库·postgresql
依晨照旧2 小时前
Langfuse 打爆两台机器:一条分位数 SQL,在 400G 表上扫了 8 分钟
数据库