Redis里头数据过期了咋删的,这些策略其实挺有讲究的,得了解下redis是怎么操作的
- 问答
- 2026-01-05 20:35:06
- 7
关于Redis如何处理过期数据,这确实是一个核心且有趣的话题,它并不是我们想当然的“一到过期时间就立刻删除”那么简单,如果真是那样,Redis作为单线程的服务器,在大量key同时过期时,就得停下所有其他命令,专门处理删除,这肯定会引起服务卡顿,Redis采用了一种“多管齐下”的混合策略,主要包含两种方法:惰性删除和定期删除,这两种方法相辅相成,在内存占用和CPU开销之间寻找平衡。
首先来说说第一种策略,叫做“惰性删除”,这个名字很形象,它的核心思想就是“不主动,不负责,等到你来访问的时候再说”,具体是怎么操作的呢?Redis并不会主动、持续地扫描所有设置了过期时间的key,看看谁到点了,而是当某个key被客户端命令访问时(比如执行GET命令),Redis会先拦一下,检查一下这个key是否设置了过期时间,如果设置了,再检查它是否已经过期,如果发现这个key已经过期了,那么Redis会立刻把这个key删除掉,然后当做这个key从来不存在一样,返回一个空值给客户端,如果key没过期,或者根本没设置过期时间,那就正常执行命令。
这种方式的好处非常明显,就是非常节省CPU资源,因为它只会在真正有访问发生的时候才进行检查和删除操作,这把删除操作的开销分摊到了每个具体的请求上,如果没有客户端来访问这个过期的key,那么哪怕它早就过期了,也会一直静静地躺在内存里,不会被立刻清理掉,这也就是惰性删除的最大缺点:会造成内存的浪费,那些再也不会被访问的过期key,会变成一种“垃圾数据”,白白占用着宝贵的内存空间,直到永远,显然,单靠这种“懒人”策略是不行的,必须得有一个主动清理的机制来配合。
就有了第二种策略,叫做“定期删除”,这个策略可以看作是惰性删除的补充,它的态度是“主动出击,但不太过频繁”,Redis会每隔一段时间,就主动地随机抽取一部分设置了过期时间的key,检查它们是否已经过期,如果过期了就删除掉,注意,这里的关键词是“定期”和“随机抽取一部分”,而不是扫描整个数据库,这个操作是由Redis的后台进程(在较新版本中)或者由主线程在特定时间点分批次完成的,试图将对正常服务的影响降到最低。
这个定期删除的过程是循环进行的,它会依次检查每一个数据库,每次从数据库中随机选出一定数量的key(比如20个)进行过期检查,删除掉其中已经过期的key之后,如果发现本轮删除的过期key数量超过了抽取数量的某个比例(比如25%),那就说明这个数据库里可能还有很多“垃圾”存在,于是它会立即再进行一轮随机抽取和删除,如此反复,直到过期key的比例降下来,它才会停下来,然后等待下一次周期性的触发,再去检查下一个数据库。
这种策略的精妙之处在于它是自适应的,如果内存中过期key很多,那么它每次检查都能清理掉很多,并且会因为比例高而持续工作,加快清理速度;如果过期key很少,它就会很快结束当前数据库的检查,减少CPU的消耗,这样就避免了在过期key不多的情况下,仍然进行全盘扫描带来的无谓开销。
Redis是通过“惰性删除”和“定期删除”这两种策略的组合拳来管理过期数据的,惰性删除确保了只有在消耗CPU的时候才做清理,而定期删除则是一个备用的保障机制,专门用来清理那些再也无人问津的过期key,防止内存被无限占用,它们俩一个“懒”,一个“勤”,共同保证了Redis在绝大多数场景下,既能高效地使用内存,又不会因为清理垃圾数据而导致服务性能出现大幅波动。
值得一提的是,除了这两种主要的删除策略,Redis还有基于内存压力触发的淘汰机制,当内存使用达到上限时,即使有些key还没过期,Redis也会根据配置的淘汰策略(如LRU、LFU等)来删除一些key以腾出空间,但这已经属于内存淘汰的范畴,和数据过期删除是两个关联但不同的概念了。

本文由颜泰平于2026-01-05发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/75153.html
