【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】-- 缓存 这篇博客。

相关推荐
睡不醒男孩0308233 小时前
第二篇:深入探索开源数据库高可用:构建基于CLup的PostgreSQL生产级高可用与读写分离架构
数据库·postgresql·开源·clup
Micro麦可乐5 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
码农阿豪5 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
鼎讯信通6 小时前
风电光缆运维提质增效:G-4000A 光缆故障追踪仪破解风场巡检难题
运维·网络·数据库
三十..6 小时前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
cfm_29147 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis
真实的菜7 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
你想考研啊8 小时前
mysql数据库导出导入
数据库·mysql·oracle
十年编程老舅9 小时前
Linux DRM:底层逻辑与实践架构
数据库·mysql
The Sheep 20239 小时前
Vue复习
linux·服务器·数据库