# Redis的过期策略是什么?
# 简要回答
- Redis 的过期策略不是“key 一到时间就立刻删除”,而是采用 惰性删除 + 定期删除 的组合方案。
- 惰性删除是指访问 key 时才检查是否过期,过期就删除;定期删除是指Redis 后台周期性抽样扫描带过期时间的 key,主动清理已经过期的数据。 这样设计是为了在 CPU 开销 和 内存占用 之间取得平衡。只用惰性删除会让很多过期 key 长时间留在内存里,只用定时删除则会带来很高的调度成本。
# 详细回答
Redis 的过期时间 Redis 可以给 key 设置 TTL(存活时间),常见命令有
EXPIRE、PEXPIRE、EXPIREAT、SET EX等。在Redis 内部会额外维护一张过期字典,记录哪些 key 配了过期时间以及具体过期时间点,只有设置了 TTL 的 key 才会进入过期策略机制。惰性删除就是“访问时才检查”。当客户端读取或操作某个 key 时,Redis 会先判断这个 key 是否已经过期:如果没过期,正常返回;如果已经过期,先删除,再返回空结果。
- 优点:对 CPU 很友好,不会主动大面积扫描
- 缺点:如果某个过期 key 一直没人访问,它可能会继续留在内存里,占着空间不释放
定期删除是为了避免大量过期 key 长期滞留,Redis 会在后台周期性地抽样检查带 TTL 的 key。如果发现已经过期的 key,就会主动删除。 这个过程不是全量扫描,而是有时间片限制的抽样删除,目的是避免因为过期清理影响主线程处理请求。
- 优点:能持续回收一部分过期数据,降低内存浪费
- 缺点:不是实时删除,所以 key 过期后,可能还会短暂存在一段时间
为什么不用定时删除
- 如果给每个 key 都维护一个定时器,到点就立刻删除,那么当 key 数量非常大时,定时任务本身会带来很大的 CPU 和调度开销。
- Redis 是内存数据库,追求高性能,因此不会采用“每个 key 一个独立定时器”的重方案。
Redis 过期策略的实际表现
当 key 到了过期时间时,不代表一定会在那个瞬间被物理删除。一个 key 过期后,可能出现以下两种情况才真正删除:被客户端再次访问到或者被后台定期扫描到。
所以业务上不能假设“TTL 一到,数据一定瞬间消失”。同时为了保证主从一致性,过期删除一般以主节点为准,再把删除动作同步给从节点。
其他常见方法
TTL/PTTL可以查看剩余过期时间。PERSIST可以移除 key 的过期时间。- 普通
SET key value会覆盖原值,同时清掉原来的 TTL;如果希望保留 TTL,可以使用KEEPTTL选项。
# 知识图解
- Redis key 的过期生命周期

# 代码示例
SET login:token:1001 abcdef EX 60
# 查看剩余过期时间
TTL login:token:1001
# 单独给已有 key 设置过期时间
EXPIRE login:token:1001 120
# 清除过期时间
PERSIST login:token:1001
# 覆盖 key 时保留 TTL
SET login:token:1001 xyz KEEPTTL
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 知识扩展
- 面试官可能追问:
- Q1:为什么 key 过期了,内存看起来还是没立刻下降?
- 因为 Redis 采用的是惰性删除和定期删除,过期时间到了不一定马上物理删除;另外内存分配器也不一定立刻把内存还给操作系统。
- Q2:为什么 Redis 不只用惰性删除?
- 如果只用惰性删除,那些“过期后再也没人访问”的 key 会一直残留在内存中,时间久了会造成明显的内存浪费。
- Q3:过期策略和淘汰策略有什么区别?
- 过期策略针对设置了 TTL 的 key,依据“是否到时间”来删除;淘汰策略针对“内存达到上限”的场景,依据配置规则选择谁被踢掉。
评论
验证登录状态...