用Redis玩转TTL过滤,数据过期啥时候删其实挺灵活的
- 问答
- 2026-01-03 20:55:24
- 8
网络技术博客与社区讨论的综合整理)
咱们今天就来聊聊Redis里面一个特别实用,但又常常让人有点疑惑的功能——TTL,也就是数据的“生存时间”,很多人用Redis就是为了它快,能当缓存,而缓存最关键的一点就是“过期删除”,不然数据一直堆在那里,内存迟早要爆掉,但数据到底啥时候被删除?这个问题,答案可不止一个,挺灵活的,理解了就能玩出花来。
最基础的就是我们主动给数据设上TTL,比如用SET key value EX 60命令,这条数据就只能活60秒,时间一到,它就该消失了,但消失的那一刻,究竟发生了什么?是不是像闹钟一样,“叮”的一声就被Redis瞬间抹掉了?其实不完全是,这里就有Redis删除过期数据的策略问题。
(来源:Redis官方文档关于过期策略的说明)
Redis为了平衡性能和内存使用,主要用了两种策略结合的方式来处理过期键,而不是傻傻地守着每个键的倒计时。

第一种策略叫做“惰性删除”,这个名字听起来有点懒,实际也挺形象的,就是当客户端尝试去访问一个键的时候,Redis才会顺便检查一下这个键有没有过期,你给一个叫user:1001:profile的键设置了10分钟的TTL,在10分钟之内,你来读它,没问题,立刻返回数据,但假如过了10分钟,你再来读,Redis在给你数据之前,会先瞄一眼它的“死亡时间”,发现“哎呦,到期了!”,那它就不会把数据给你了,而是直接告诉你“这个键不存在”,同时顺手就把这个键从数据库里给删了,这种策略的好处是特别省CPU,只在必要的时候才干活,不会为了检查成千上万个键的过期时间而浪费资源,但坏处也很明显,万一有个键永远没人来访问了,但它又过期了,那它就会一直占着茅坑不拉屎,白白浪费内存,直到有一天被人想起来访问为止。
光靠“惰性删除”这个懒家伙肯定不行,所以Redis还有个第二种策略,叫做“定期删除”,这个就像是个定时巡逻的保安,Redis会每隔一段时间(默认是每秒10次,也就是100毫秒一次)就主动抽出一小会儿工夫,从设置了过期时间的键里面,随机抽查一批(比如20个),检查它们是否过期,如果过期了,就直接删除,如果发现这批键里有过期的比例很高,比如超过25%,那Redis就会觉得“这一片区域过期键不少啊”,然后它就会紧接着再随机抽查一批,继续删除,直到过期键的比例降下来为止,这种策略是对“惰性删除”的有效补充,专门清理那些“僵尸”键,防止内存被无谓地占用。
(来源:Redis源码分析及相关技术解读)

我们把这两种策略结合起来看,一个数据的具体死亡时间点就不是绝对精确的了,它可能是在过期的那一刻之后,第一次被访问时被“惰性删除”的;也可能是在过期之后,某次“定期删除”巡逻时被逮到并清理的,你的数据寿命可能比设定的TTL长那么一点点,但这通常是可接受的,因为Redis会努力把内存控制在合理范围内。
理解了这两种删除策略,我们就可以玩转TTL来做一些有趣的事情了,实现一个简单的“频率限制”功能,防止恶意刷接口,你可以给每个用户ID和操作(发帖”)设一个键,rate_limit:user123:post,每次用户发帖前先检查这个键是否存在,如果存在就说明操作太频繁了,拒绝请求;如果不存在,就设置这个键,并给它一个短的TTL,比如30秒,这样,30秒内用户再次发帖就会被限制,30秒后,这个键会被Redis自动清理掉(通过定期删除或惰性删除),用户就又可以发帖了,你完全不需要自己写个定时任务去清理这些临时键,非常省心。
再比如,做“缓存雪崩”的防护,如果大量缓存数据在同一时刻过期,会导致所有请求都砸到数据库上,数据库可能就扛不住了,一个常见的解决办法就是,在设置缓存TTL的时候,不要用一个固定的数值,比如都设成60分钟,而是在这个基础上加一个随机数,比如60*60 + random(0, 300),让过期时间分散开,这样,即使这些数据是同一时间被创建的,它们也会在不同的时间点被Redis清理掉,请求会平摊到数据库上,避免了瞬间的压力高峰,这里就利用了TTL删除不是瞬间完成的特性,通过分散过期时间,巧妙地化解了风险。
还有更高级的玩法,比如用TTL来实现“延迟队列”,你可以把需要延迟执行的任务信息存入Redis,并设置一个延迟时间作为TTL,然后起一个进程,不断地用BRPOP之类的命令尝试从队列里取数据,因为数据有过期时间,等时间一到,它要么被定期删除策略清理掉,要么在被获取时因过期而被惰性删除,你的进程就能感知到并开始处理下一个任务,更严谨的做法是使用Sorted Set,但基于TTL的思路也是一种简单的实现。
别看TTL就是个简单的过期时间,背后是Redis精心设计的删除策略在支撑,它不是死板地到点就删,而是灵活地、在保证性能的前提下尽可能地及时清理,我们知道了这个机理,就可以不仅仅把它当作一个让缓存失效的工具,而是可以利用这种“不确定性”和“自动清理”的特性,来设计出更健壮、更巧妙的系统功能,说白了,就是摸清了Redis的脾气,然后让它更好地为我们打工。
本文由革姣丽于2026-01-03发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/73919.html
