Redis如何实现到期删除的?
作者:程序员马丁
热门项目实战社群,收获国内众多知名公司面试青睐,近千名同学面试成功!助力你在校招或社招上拿个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 指令介绍
当然,为了面试的时候有更多可说的,我们可以适当的扩展一下,介绍一下常见的几种实现方式,和它们的优缺点: