【Redis】-- key的过期策略

redis中key的过期策略

  • [1. 定时器的实现原理](#1. 定时器的实现原理)
    • [1.1 基于优先级队列/堆](#1.1 基于优先级队列/堆)
    • [1.2 基于时间轮实现的定时器](#1.2 基于时间轮实现的定时器)
  • [2. Redis中key的过期策略](#2. Redis中key的过期策略)
    • [2.1 定期删除](#2.1 定期删除)
    • [2.2 惰性删除](#2.2 惰性删除)

更多Redis相关内容,请关注 Redis专栏。

提到过期策略,我们的第一反应可能是使用定时器(在某个时间到达之后,执行指定的任务)。

1. 定时器的实现原理

1.1 基于优先级队列/堆

优先级队列是按照指定优先级,优先级高的先出,优先级低的后出。

这个优先级,是自定义的。在redis过期key的场景中,可以将优先级定义为"过期时间越早,优先级越高"。我们就可以把这些设置了过期时间的key加入到一个优先级队列中,并且按照上面的定义设置优先级。

那么,毫无疑问的,这个优先级队列的队首元素就是过期时间最早的,此时可以给这个优先级队列分配一个线程,让这个线程检查队首元素是否过期。

但是该线程不能检查的太频繁,否则CPU一直空转,会消耗资源。

为了解决这个问题,我们可以给该线程根据队首元素的过期时间,给线程设置一个等待,时间到了,就唤醒该线程。如果在线程休眠的时刻,来了一个过期时间比队首元素更早的key,只需要在添加新任务的时候,唤醒一下该线程,重新检查队首元素,再根据过期时间重新调整阻塞时间即可。

1.2 基于时间轮实现的定时器

把时间划分成很多个小段,具体要分成多少个小段,一个小段多长时间,需要根据实际的业务需求来进行设定。

在每个小段上都挂着一个链表,链表中的每个节点都代表一个要执行的任务。指针会每个固定的时间间隔(每个小格子的时间)移动,每走到一个新的各自上就会尝试将链表上的任务执行一下(有可能任务还没有到达过期时间,就会执行不成功)。

假设现在来了一个过期时间为200ms的key,就会放到指针当前指向的小格子后的第二个格子里面。

但是Redis并没有采取上述的方案。

2. Redis中key的过期策略

2.1 定期删除

如果直接遍历所有的key,肯定是行不通的。因为redis是单线程的程序,主要的任务就是处理每个命令,如果key的数量太大,就会消耗太多时间,导致正常处理命令被阻塞住了。

所以redis采用每次抽取一部分,来验证时候到达过期时间,来保证这个抽取检查的过程足够快。

2.2 惰性删除

惰性删除就比较符合懒人的心理了,用我妈的话来说就是"早了不动,晚了挠腚"🤦‍♀️。

我们假设key已经到了过期时间了,但是并不会删除它,它还存在,知道一次访问,正好用到了这个已经过期了的key,此时就会让redis服务器出发删除该key的操作,同时给客户端返回一个nil。

redis采取的上述两种策略的结合,但是整体的效果一般,仍然会有很多过期的key的删除不及时。

redis为此还提供了一系列的内存淘汰机制。参考 【Redis】-- 缓存 这篇博客。

相关推荐
weixin1997010801616 小时前
废旧物资 item_search - 按关键字搜索商品列表接口对接全攻略:从入门到精通
数据库·python
l1t16 小时前
快速加载CSV文件到数据库的工具pg_csv_loader
数据库·算法
无忧智库16 小时前
深度拆解:某大型医院“十五五”智慧医院建设方案,如何冲刺互联互通五级乙等?(附技术架构与实施路径)
java·数据库·架构
moxiaoran575316 小时前
Java使用Redis ZSet恢复用户能量
数据库·redis·哈希算法
wtsolutions16 小时前
Sheet-to-Doc模板设计最佳实践:创建专业的Word模板
前端·javascript·数据库
辞砚技术录16 小时前
MySQL面试题——索引、B+树
数据结构·数据库·b树·面试
风吹落叶花飘荡17 小时前
mysql数据库创建新用户,并只给其必要的权限
数据库·mysql
悦数图数据库17 小时前
“复旦大学—杭州悦数先进金融图技术校企联合研究中心年度总结会”圆满举行
大数据·数据库·人工智能
TDengine (老段)17 小时前
TDengine Rust 连接器入门指南
大数据·数据库·物联网·rust·时序数据库·tdengine·涛思数据