Redis 如何配置 Key 的过期时间?它的实现原理?

Redis 配置 Key 过期时间主要通过 4个核心命令 实现,其底层依赖"过期字典+三种过期删除策略"协同工作,在保证内存不溢出的同时平衡性能损耗。

一、Key 过期时间的配置方式

通过以下命令为 Key 设置或管理过期时间,过期后 Key 会被自动删除(或标记为删除):

  • EXPIRE key seconds:为已存在的 Key 设置过期时间(单位:秒),如 EXPIRE user:100 3600(用户100的缓存1小时后过期)。

  • PEXPIRE key milliseconds:与 EXPIRE 功能一致,单位改为毫秒,支持更精细的过期控制。

  • SET key value EX seconds:创建 Key 时直接附带过期时间(原子操作),如 SET product:200 apple EX 1800(商品200的缓存30分钟后过期),避免"先创建Key再设过期"的中间态问题。

  • PEXPIREAT key timestamp-ms:指定 Key 过期的"毫秒级时间戳"(如 PEXPIREAT order:300 1717248000000),适用于需在固定时间点过期的场景(如凌晨3点清理当日日志Key)。

此外,可通过 TTL key 查看 Key 剩余过期时间(返回秒数,-1表示永不过期,-2表示已过期),PTTL key 则返回毫秒数。

二、过期时间的实现原理

Redis 并非"过期后立即删除Key",而是通过"过期字典记录过期时间+三种删除策略组合"实现高效管理,核心逻辑如下:

1. 过期字典:记录过期时间

Redis 内部维护一个"过期字典"(本质是哈希表),key 是待过期的 Redis Key,value 是该 Key 的过期时间戳(秒或毫秒)。当为 Key 设置过期时间时,会同时在过期字典中添加一条记录;删除 Key 或 Key 过期后,会从过期字典中移除对应记录。

2. 三种过期删除策略:平衡"内存占用"与"性能损耗"

由于"立即删除所有过期Key"会导致CPU占用过高(频繁扫描),"永不主动删除"会导致内存溢出,Redis 采用三种策略结合:

策略1:惰性删除(Lazy Delete)

仅在"访问 Key 时"检查是否过期(如执行 GET key),若过期则立即删除并返回 nil。优点是不消耗额外CPU(只在访问时处理),缺点是可能导致"过期Key长期占用内存"(如长期不访问的过期Key)。

策略2:定期删除(Periodic Delete)

Redis 每隔100毫秒(默认)会随机扫描"过期字典"中的部分 Key(如每次扫描20个),若扫描到过期Key则删除;若单次扫描中过期Key占比超过25%,会重复扫描(最多重复10次),避免大量过期Key堆积。该策略平衡了CPU和内存,是过期删除的核心。

策略3:内存淘汰(Memory Eviction)

当 Redis 内存达到 maxmemory 上限时,会触发"内存淘汰策略"(如 allkeys-lru 淘汰最近最少使用的Key),即使Key未到过期时间,也会被删除以释放内存。该策略是"过期删除"的兜底,确保内存不溢出。

相关推荐
渣哥27 分钟前
从 READ_UNCOMMITTED 到 SERIALIZABLE:Spring 事务隔离级别全解析
javascript·后端·面试
Codelinghu42 分钟前
【bug】大模型微调bug:OSError: Failed to load tokenizer.| Lora
后端
Frank_zhou43 分钟前
虚拟线程池
后端
aiopencode1 小时前
iOS混淆与IPA加固实战手记,如何构建苹果应用防反编译体系
后端
cxyxiaokui0011 小时前
JDK 动态代理 vs CGLIB:原理、区别与 Spring AOP 底层揭秘
java·后端·spring
00后程序员张1 小时前
Swoole HTTPS 实战,在生产环境部署、性能权衡与排查流程
后端·ios·小程序·https·uni-app·iphone·swoole
我命由我123451 小时前
PDFBox - PDDocument 与 byte 数组、PDF 加密
java·服务器·前端·后端·学习·java-ee·pdf
考虑考虑1 小时前
go格式化时间
后端·go
星球奋斗者2 小时前
计算机方向如何才能更好的找到工作?(成长心得)
java·后端·考研·软件工程·改行学it
海梨花2 小时前
【八股笔记】SSM
java·开发语言·笔记·后端·面试·框架