Redis里那些过期数据到底咋处理,读取时又会发生啥情况呢?
- 问答
- 2025-12-27 17:13:16
- 1
主要参考自Redis官方文档关于过期键的处理机制部分,并结合了《Redis设计与实现》一书中的相关阐述)
我们得明白Redis是怎么给数据设置过期时间的,你可以想象一下,Redis就像一个自带日历和闹钟的超级管理员,当你往Redis里存一个键值对的时候,比如一个叫“user_session:123”的用户会话,你可以同时告诉它:“这个数据只能活300秒”,Redis管理员就会在自己的小本本上记下:“user_session:123”这个家伙,将在未来的某个精确时间点(当前时间+300秒)过期。
关键问题来了,到了那个时间点,或者过了那个时间点,Redis会怎么处理这个“过期”的数据呢?它是不是一到点就立刻把它从家里扔出去?答案没那么简单,Redis实际上用了两种主要的策略来清理这些过期数据,一种叫“惰性删除”,另一种叫“定期删除”,你可以把它们理解成一个“懒汉”和一个“钟点工”的组合拳。
第一招:惰性删除——等你要用的时候再说
惰性删除,顾名思义,懒惰”的删除方式,Redis不会时时刻刻盯着所有有过期时间的键,看它们是不是到点了,那样的话,Redis就别干别的了,光看表就行了,太浪费精力(CPU资源)。

那它什么时候才动手呢?就是在你读取这个键的时候,5分钟过去了,你突然发来一个命令:“给我看看user_session:123的值”,Redis管理员在把值交给你之前,会先低头看一眼自己的小本本,查一下这个键的过期时间。
这时候会发生两种情况:
- 如果发现这个键已经过期了:Redis会立刻毫不犹豫地把这个键从数据库里删除掉,然后就好像这个键从来不存在一样,给你返回一个
nil(也就是空值),你的感觉就是“这个会话不存在或者已经失效了”。 - 如果发现这个键还没过期:那太好了,Redis就会把新鲜的值正常返回给你。
这种策略的好处非常明显:它把删除操作的成本分摊到了每一次读取命令上,只有被访问到的键才会被检查是否过期,如果一个键过期后永远没人再来访问,那它就永远占着那块地方吗?也不是,这就引出了第二个策略。
第二招:定期删除——定时打扫一下房间

光靠“惰性删除”有个问题,就是如果有很多键过期了,但一直没人来读,那这些“僵尸”数据就会一直占用着宝贵的内存空间,导致内存浪费,Redis可不想让自己的房子变成垃圾场。
它又请了一个“钟点工”,这个钟点工会每隔一段时间就主动来打扫一下房间,这个“定期删除”策略是这样的:Redis会每隔100毫秒(默认值)左右,就随机地从数据库中抽取一定数量的键(比如20个),检查它们是否过期,如果发现有过期的,就把它删掉。
这个过程是分批次、小范围进行的,不会一次性扫描所有键,以免对性能造成太大影响,它就像是你每隔一会儿就收拾一下桌子的一个角落,而不是每次都把整个家翻个底朝天,通过这种间歇性的打扫,就能及时清理掉那些长期没人访问的过期数据,释放内存。
两种策略的配合与读取时的具体情形

现在我们把“懒汉”和“钟点工”的工作结合起来,就能完整回答“读取时会发生啥”这个问题了。
当你尝试读取一个键时,完整的流程是这样的:
- 惰性删除首先触发:Redis先检查这个键是否存在,如果键都不存在,直接返回空。
- 如果键存在:Redis会严格地检查它是否设置了过期时间,并且是否已经过期。
- 若已过期:立即删除该键,然后向你返回空值,这个删除操作是同步的,也就是说,在你得到响应之前,删除动作必须完成。
- 若未过期或未设置过期时间:正常返回对应的值。
你永远不可能读到一个已经过期的值,Redis在逻辑上保证了,只要它能返回给你一个值,这个值就肯定是“新鲜”的(在过期时间内),这种机制对于像会话管理、验证码缓存、限流计数等需要严格过期逻辑的场景至关重要。
一些额外的细节和影响
- 性能影响:惰性删除对单个命令的延迟可能有细微影响,因为多了一个检查步骤,但这通常可以忽略不计,定期删除是后台操作,通过合理的配置,可以避免对主线程造成明显卡顿。
- 内存回收:即使有定期删除,在极端情况下,如果瞬间有大量键同时过期,而定期删除还没来得及清理,可能会导致内存使用率瞬间升高,一旦下一次清理周期到来,这些内存就会被回收。
- 复制和持久化时的处理:在Redis主从复制模式下,删除过期键的动作是由主节点(Master)控制的,主节点在删除一个过期键后,会向所有从节点(Slave)发送一个明确的删除命令,从而保证主从数据的一致性,在持久化(RDB或AOF)时,过期的键不会被保存到快照或日志中。
Redis通过“惰性删除”和“定期删除”这两种相辅相成的策略,巧妙地平衡了性能和内存效率,在你读取数据时,它通过“惰性删除”确保了你得到的结果一定是有效的;而通过“定期删除”,它又在后台默默地清理垃圾,防止内存被无用的数据占满,这套机制虽然听起来简单,但设计得非常精妙,是Redis保持高效稳定运行的关键之一。
本文由召安青于2025-12-27发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/69531.html
