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

相关推荐
有想法的py工程师2 小时前
PostgreSQL 分区表排序优化:Append Sort 优化为 Merge Append
大数据·数据库·postgresql
迷枫7123 小时前
达梦数据库的体系架构
数据库·oracle·架构
夜晚打字声3 小时前
9(九)Jmeter如何连接数据库
数据库·jmeter·oracle
Chasing__Dreams3 小时前
Mysql--基础知识点--95--为什么避免使用长事务
数据库·mysql
风吹迎面入袖凉3 小时前
【Redis】Redis的五种核心数据类型详解
java·redis
NineData4 小时前
NineData 智能数据管理平台新功能发布|2026 年 3 月
数据库·oracle·架构·dba·ninedata·数据复制·数据迁移工具
小陈工4 小时前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python
❀͜͡傀儡师4 小时前
k8s部署的Nexus 3 数据库损坏恢复指南:从删除损坏数据库到完整数据重建
数据库·kubernetes·nexus3
StackNoOverflow5 小时前
Spring Security权限控制框架详解
java·数据库·sql
不愿透露姓名的大鹏5 小时前
Oracle归档日志爆满急救指南
linux·数据库·oracle·dba