Redis过期的Key到底会不会自己消失,自动删不删除这个事儿解析一下
- 问答
- 2026-01-14 22:49:18
- 2
关于Redis里设置了过期时间的Key到底会不会自动删除,答案是肯定的:会,Redis设计了这个机制,就是为了避免内存被无用的数据无限期占用,这个“自动删除”并不是像闹钟一样,时间一到“叮”的一声就立刻精准删除,它背后其实有几种不同的策略在协同工作,理解这些策略能帮助我们更好地使用Redis。
Redis处理过期Key主要有两种策略:惰性删除 和 定期删除,这两种方式不是二选一,而是互相配合,共同保证内存的回收。
第一种策略:惰性删除——等用到的时候再检查
这个名字听起来有点懒,但很形象,它的核心思想是:只有当某个Key被访问的时候,Redis才会去检查它是否已经过期。
具体过程是这样的:当你尝试用GET命令去读取一个Key,或者用DEL命令之外的其他命令触及这个Key时,Redis会先翻看一下这个Key的“身份证”(也就是它的过期时间),如果发现这个Key已经过期了(当前时间大于设置的过期时间),那么Redis会立刻做两件事:
- 当场把这个过期的Key从内存中删除掉。
- 返回一个空值(比如
(nil)),就像这个Key从来不存在一样。
这种方式的优点非常明显:它非常节省CPU资源,因为只有在真正有请求来的时候才进行检查和删除操作,不会在后台无缘无故地消耗计算能力,如果一堆Key设了过期时间但一直没人访问,那么Redis也不会主动去管它们。
但它的缺点也同样突出:如果大量过期的Key永远不再被访问,那么它们就会一直赖在内存里,成为“僵尸Key”,即使它们逻辑上已经失效了,但物理上依然占据着宝贵的内存空间,这显然是不可接受的,因为内存总有一天会被这些垃圾数据塞满,为了解决这个问题,Redis引入了第二种策略。
第二种策略:定期删除——定时主动抽查清理
为了弥补惰性删除的不足,Redis又设置了一个“保洁阿姨”的角色,它会定期主动地扫描数据库,找出并删除那些已经过期的Key,这个过程是Redis在后台自动进行的。
这个“定期”并不是指固定频率,而是有一套自适应的算法,Redis会定期从每个数据库中随机抽取一小部分(比如20个)设置了过期时间的Key,检查它们是否过期,如果过期的比例很高,说明这个数据库里垃圾很多,Redis就会继续从这批Key中再抽取一批进行检查,如此循环,直到过期的比例降下来,如果一开始抽查的样本中过期Key就很少,说明内存还算干净,“保洁阿姨”就会偷个懒,提前结束本轮清扫,等待下一次周期。
这种策略的优点是解决了“僵尸Key”的问题,能够在一定程度上主动释放内存。缺点是它依然是一个抽样检查,不可能在每一轮中都扫描所有的Key,所以仍然会存在一些“漏网之鱼”,它也会对CPU造成一定的压力,尤其是在过期Key非常多的情况下。
两种策略的配合
Redis的过期Key清理是“惰性删除”和“定期删除”双管齐下的结果,你可以这样理解:
- 定期删除像是集中大扫除,每隔一段时间清理掉大部分明显的垃圾。
- 惰性删除像是随手保洁,用到什么东西时发现坏了就顺手扔掉。
两者结合,既避免了CPU持续高负荷运转,又保证了内存不会因为大量过期Key堆积而耗尽。
补充一点:内存满了怎么办?
除了上述两种常规操作,Redis还有一个终极武器——内存淘汰策略,当Redis的内存使用达到上限时,如果此时再要写入新的数据,Redis就会根据你配置的策略(maxmemory-policy)来采取行动。
其中一些策略就和过期Key直接相关,
volatile-lru:尝试淘汰那些设置了过期时间的Key中,最近最少使用的。volatile-ttl:尝试淘汰那些设置了过期时间的Key中,剩余生存时间(TTL)最短的,也就是最快就要过期的。
这些策略会在内存不足时,更加积极地去清理那些“可能没用”或“即将失效”的Key,为新数据腾出空间,如果所有带过期时间的Key都被淘汰光了,内存还是不够,那么根据配置,Redis可能会报错或者开始淘汰那些没设过期时间的Key。
总结一下
回到最初的问题:Redis过期的Key会自己消失吗?会消失,但它不是瞬间消失,而是通过“惰性删除”(访问时检查)和“定期删除”(后台抽样)两种方式逐步清理的,这种设计是在CPU消耗和内存释放之间取得的一个平衡,作为使用者,我们只需要知道Redis最终会帮我们处理好就行了,但了解其原理有助于我们在遇到内存问题时,能更准确地判断原因。
(参考资料:Redis官方文档中关于“Expiration”的章节)

本文由酒紫萱于2026-01-14发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/80808.html
