浅谈Redis(2)

一.提出问题

当我们给 Redis 海量 Key 设置了过期时间,Redis 如何感知哪些 Key 已过期、需要回收,哪些仍在有效期?Redis 通过过期键删除策略管理过期数据,官方采用「惰性删除 + 定期删除」组合方案实现过期键清理。

二.redis的过期策略

1.惰性删除(被动删除)

当redis中某个键过期了,不会立刻被删除,等到下一次,客户端访问这个键时,redis会先检验过期状态,若已过期当场删除,再返回空数据

  • 优点:CPU 开销极小,仅在访问时触发检查,闲置 CPU 无无效扫描
  • 缺点:内存浪费风险大。若过期 Key 长期不再被访问,会永久驻留内存,成为僵尸数据

2.定时删除

设置固定周期(默认 100ms),每隔这个时间就从 Redis 里随机抽取指定数量的键,挨个检查是否过期,查到过期键就直接删除

优点:主动释放过期内存,规避惰性删除长期堆积过期 Key 的问题

缺点:Redis 只做抽样抽查,海量过期 Key 可能单次扫不完

并不是采取某一种策略,而是两种策略结合使用

三.使用定时任器删除过期键

1.使用优先级队列

**思路:**创建一个优先级队列 (过期时间早的,优先级高),将被设置了过期时间的键,按照优先级顺序依次放入优先级队列中,最先过期的键放置在队首。定时器开启一个线程只扫描队首的键是否过期(队首是全队列最先过期的数据,队首没到期,队列里剩下所有键都没过期);如果键过期就出队删除,原第二位的键变成新队首,循环处理;没到过期时间,就根据当前时间和队首过期时间算出休眠时长,线程休眠,避免频繁空扫描浪费 CPU,等到休眠结束唤醒线程,再次校验队首。

2.使用时间轮

指针每转到一格,就遍历当前格子链表,删除里面所有过期Key

补充:(1)如果 key 过期时间超过单圈总时长,就挂载多圈标记,指针多转几圈后再处理。

**(2)**单个格子代表100ms时间粒度

相关推荐
小七-七牛开发者5 小时前
TokenPilot:让 LLM Agent 长会话成本降 60%+ 的上下文管理
缓存·agent·token·context·上下文·推理成本
ClouGence10 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将13 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波2 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_3 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
用户3169353811835 天前
Java连接Redis
redis
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
冬奇Lab6 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence6 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle