redis过期时间和删除策略

本文介绍了Redis中四种设置键过期时间的方法,并详细解释了Redis如何通过惰性删除与定期删除相结合的方式管理过期键,确保内存高效利用。

在redis中有4种方法可以设置过期时间: 

expire<key> <ttl>: 设置生存时间为ttl秒

pexpire<key><ttl>: 设置生存时间为 ttl毫秒

expireat <key> <timestamp> : 设置过期时间为timestamp所指定的秒数时间戳.

pexpireat<key><timestamp>: 设置过期时间为timestamp所指定的毫秒数时间戳.

其中timestamp为unix时间戳.


redisDb结构的expires字典保存了数据库中所有键的过期时间.它的数据结构由两部分组成:

1.过期字典的键是一个指针,它指向键空间中的某个键对象.

2.过期字典的值是一个long long类型的整数,它保存的就是键的过期时间.


在redis中有三种不同的删除过期键的策略:

1.惰性删除

2.非惰性删除:a.定时删除  b.定期删除


redis服务器采用的策略是惰性删除和定期删除的组合.

惰性删除由db.c/expireIfNeeded函数实现.

定期删除由redis.c/activeExpireCycle函数实现:每当redis的服务器周期性操作redis.c/serverCron函数执行时, activeExpireCycle函数就会被调用,它在规定时间内,分多次 遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键.


<think>嗯,用户这次聚焦在Redis过期时间设置过期策略上,看来ta正在深入理解缓存管理机制。此前对话中我已经解释了Redis同步机制,现在需要切换到数据淘汰维度。用户引用的资料相当全面,从过期策略类型到内存淘汰机制都有覆盖,说明ta做了预习。 用户可能是个后端开发者,正在设计缓存系统。ta特意提到“短信验证码”这种典型用例,说明需要实战指导。虽然引用资料完整,但三大策略的优缺点分散在不同条目里,需要我重新整合。定时删除的实时性优势(引用[2][3])性能缺陷(引用[3])要对比着说,而惰性删除的内存泄漏风险(引用[2])正好能被定期删除弥补(引用[2][4])。 内存淘汰策略部分有个细节要注意:引用[5]提到默认策略是noeviction,但实际生产环境更常用volatile-lru。这个矛盾点需要解释清楚——开发环境默认防止数据丢失,线上则需主动淘汰。用户如果设置过期时间却没配淘汰策略,可能踩坑。 接下来组织逻辑链:先讲如何设置过期时间(基础操作),再分析策略实现(技术原理),最后落地到配置建议(实战)。EXPIRE命令的毫秒级精度(引用[1])TTL返回值(引用[4])这类API细节不能漏。对于时间单位混淆这个常见错误,要强调EXPIREPEXPIRE的区别。 用户没问但应该补充的是策略选择依据:比如金融交易类系统适合定时删除保证实时性,电商大促时用定期删除更稳妥。这些在“业务场景”段落用案例说明会更直观。最后的三个相关问题覆盖了配置(时间单位)、监控(淘汰统计)设计(无过期数据管理),正好形成知识闭环。 </think>### Redis过期时间设置策略详解 #### **一、过期时间设置方法** 1. **基础命令** - `EXPIRE key seconds`:设置键的生存时间(秒级) - `PEXPIRE key milliseconds`:毫秒级精度设置 - `EXPIREAT key timestamp`:指定UNIX时间戳过期 ```bash # 示例:设置键"code:123"在300秒后过期 127.0.0.1:6379> SET code:123 "ABCD" 127.0.0.1:6379> EXPIRE code:123 300 ``` 2. **原子操作** - `SET key value EX seconds`:设值同时设置过期时间(替代`SET`+`EXPIRE`) ```bash # 示例:设值并设置60秒过期 127.0.0.1:6379> SET session:user1 "data" EX 60 ``` 3. **查询与取消** - `TTL key`:查看剩余生存时间(秒),返回`-2`表示键不存在,`-1`表示永不过期 - `PERSIST key`:取消过期时间转为永久存储[^1] #### **二、过期策略实现原理** Redis 采用 **惰性删除 + 定期删除** 组合策略(默认配置): 1. **惰性删除(Lazy Deletion)** - **触发条件**:每次访问键时检查过期时间 - **流程**: $$ \text{读请求} \rightarrow \text{检查TTL} \xrightarrow{\text{已过期}} \text{删除键} \rightarrow \text{返回nil} $$ - **优点**:CPU消耗低,无额外扫描开销 - **缺点**:长期不访问的过期键会占用内存[^2][^3] 2. **定期删除(Periodic Deletion)** - **工作机制**: - 每隔`100ms`随机抽取部分过期键(默认扫描`20`个键/次) - 删除其中已过期的键,若过期键比例超`25%`则重复扫描 - **核心参数**(redis.conf): ```conf hz 10 # 每秒执行10次定期扫描(可调整) maxmemory-samples 5 # LRU/LFU淘汰算法采样数量 ``` - **平衡点**:在内存清理效率与CPU消耗间取得平衡[^2][^4] > ⚠️ **定时删除策略未被采用的原因**: > 为每个键创建定时器会消耗大量内存CPU资源,在高并发场景可能引发性能雪崩[^3]。 #### **三、内存淘汰策略** 当内存达`maxmemory`限制且新数据写入时触发(需显式配置): | **策略** | **作用范围** | **规则** | |----------|--------------|----------| | `volatile-lru` | 仅过期键 | 淘汰最近最少使用的键 | | `volatile-ttl` | 仅过期键 | 淘汰剩余生存时间最短的键 | | `volatile-random` | 仅过期键 | 随机淘汰过期键 | | `allkeys-lru` | 所有键 | 全局LRU淘汰 | | `allkeys-random` | 所有键 | 全局随机淘汰 | | `noeviction`(默认) | - | 拒绝写入并返回错误 | **配置命令**: ```bash # redis.conf 中设置 maxmemory 2gb maxmemory-policy volatile-lru ``` #### **四、业务场景建议** 1. **短信验证码** - 使用`SET code:138xxxx EX 120`(120秒自动过期)[^4] 2. **会话缓存** - 结合`volatile-ttl`确保及时清理过期会话 3. **热点数据缓存** - 永不过期键 + `allkeys-lru`策略,通过程序更新缓存 4. **高并发系统** - 避免使用`volatile-lfu`(访问频率统计消耗CPU) > 📌 **关键实践**: > - 优先对**可再生数据**设置过期时间(如验证码、临时token) > - **核心业务数据**建议采用程序主动更新而非依赖自动淘汰 > - 监控`expired_keys`指标:`redis-cli info stats | grep expired_keys` --- ### 相关问题 1. Redis 的 `EXPIRE` 命令与 `PEXPIRE` 命令在实现上有何本质区别? 2. 如何监控 Redis 实例中因过期策略失效导致的内存泄漏问题? 3. 在 `noeviction` 策略下,若数据已满且无过期键,写操作会如何响应? 4. 为什么生产环境推荐使用 `volatile-lru` 而非默认的 `noeviction`? [^1]: 基于本机内存的缓存场景 [^2]: Redis 过期策略类型 [^3]: 定时删除策略的优缺点 [^4]: 过期时间的应用场景 [^5]: 内存淘汰机制配置
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值