Redis如何实现到期删除的?
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
答题思路
回答话术
在 Redis 中,我们可以用 EXPIRE、PEXPIRE、EXPIREAT 和 PEXPIREAT四个命令来按毫秒或 秒设置 Key 的过期时间。其中,前两者指定的是 Key 的有效时间,而后两者指定的是 Key 的到期时间点。
这些时间最终会被转换为一个时间戳并,与 Key 一一对应保存在一个到期字典中,然后 Redis 会根据 Key 在到期字典中的到期时间,通过主动和被动两种方式清理到期的 Key。
被动删除是指每次访问 Key 键时,Redis 会检查 Key 是否已到期,如果是就将其删除并返回空值。不过如果仅靠被动删除是不够的,因为如果 Key 的访问频率不高,可能会导致一些数据一直不能被删除,内存也无法得到释放,因此所以还需要定期的主动删除。
主动删除是指 Redis 会每秒主动扫描 10 次到期字典,随机抽取 20 个 Key 并删除其中已经到期的部分。然后,如果这次抽样中到期键的 Key 的比例超过 25%,就会继续抽样,直到不满足条件或超时为止。
以上两种删除机制互相配合,基本能保证 Redis 中到期键的数量不会超过总数据量的 25%。
另外,Redis 在持久化的时候也会针对到期的 Key 做额外的处理。Redis 在 AOF 的时候,如果 Key 过期了,则会向文件追加一条 DEL 指令,而如果是在 AOF 重写和 RDB 的时候,则检查并直接忽略掉过期的 Key。
最后是集群,在集群里面,当主节点发现 Key 到期时,会向所有从节点发送 DEL 命令,但是当从节点发现键到期时,只会将其标记为已删除,直到收到主节点的删除指令才会真正删除,以确保数据一致性。
问题详解
1. 到期时间
在 Redis 中,你可以使用以下四种命令为 Key 设置到期时间:
EXPIRE:以秒为单位,设置 Key 的有效时间。PEXPIRE:以毫秒为单位,设置 Key 的有效时间。EXPIREAT:以秒为单位,设置 Key 的到期时间戳。PEXPIREAT:以毫秒为单位,设置 Key 的到期时间戳。
其中,前两者指定的是 Key 的有效时长,而后两者指定的是 Key 到期时间点。
不过,在 Redis 底层实现中,四种命令最终都会变为 Key 到期时间点对应的时间戳,并被记录在一个到期字典中(哈希表)。
2. Redis 的删除策略
按官方文档的说法,Redis 的过期删除有两种方式:
- 主动删除:每 10 秒扫描一次数据库,随机抽 20 个 key,并删除其中到期的 key。如果到期 Key 占比超过 25%,那么继续抽样,直到不满足条件或超时为止;
- 被动删除:访问 Key 时检查到期时间,如果已经到期就删除;
官方文档对此进行了解释:Redis 官网 -- EXPIRE 指令介绍
当然,为了面试的时候有更多可说的,我们可以适当的扩展一下,介绍一下常见的几种实现方式,和它们的优缺点: