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

相关推荐
2301_763472461 天前
使用PyQt5创建现代化的桌面应用程序
jvm·数据库·python
爱学习的阿磊1 天前
Web开发与API
jvm·数据库·python
阳光九叶草LXGZXJ1 天前
达梦数据库-学习-50-分区表指定分区清理空洞率(交换分区方式)
linux·运维·数据库·sql·学习
Data_Journal1 天前
【无标题】
大数据·服务器·前端·数据库·人工智能
qq_192779871 天前
Python多线程与多进程:如何选择?(GIL全局解释器锁详解)
jvm·数据库·python
亚控科技1 天前
超大型数据中心冷源群控升级:自主可控与智能调控的实践
数据库·智慧楼宇·kingscada·亚控科技·信创scada·大型数据中心
naruto_lnq1 天前
NumPy入门:高性能科学计算的基础
jvm·数据库·python
Apple_羊先森1 天前
ORACLE数据库巡检SQL脚本--4、检查锁阻塞
数据库·sql·oracle
2301_822365031 天前
实战:用Python分析某电商销售数据
jvm·数据库·python
zhangyifang_0091 天前
ClickHouse查询报错:Code: 62. DB::Exception: Max query size exceeded:
数据库·clickhouse