Redis-3种过期策略

本文探讨了Redis中处理过期键值的三种策略:定时删除、惰性删除及定期删除。介绍了每种策略的工作原理、优缺点及其应用场景。特别强调了Redis如何结合惰性删除与定期删除来优化内存管理。

定时删除
含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
优点:保证内存被尽快释放
缺点:
若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key
定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重
没人用
惰性删除
含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。
优点:删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了)
缺点:若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)
定期删除
含义:每隔一段时间执行一次删除(在redis.conf配置文件设置hz,1s刷新的频率)过期key操作
优点:
通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用–处理"定时删除"的缺点
定期删除过期key–处理"惰性删除"的缺点
缺点
在内存友好方面,不如"定时删除"
在CPU时间友好方面,不如"惰性删除"
难点
合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)(这个要根据服务器运行情况来定了)
看完上面三种策略后可以得出以下结论:
定时删除和定期删除为主动删除:Redis会定期主动淘汰一批已过去的key

惰性删除为被动删除:用到的时候才会去检验key是不是已过期,过期就删除

惰性删除为redis服务器内置策略

定期删除可以通过:

第一、配置redis.conf 的hz选项,默认为10 (即1秒执行10次,100ms一次,值越大说明刷新频率越快,最Redis性能损耗也越大)
第二、配置redis.conf的maxmemory最大值,当已用内存超过maxmemory限定时,就会触发主动清理策略
注意:

上边所说的数据库指的是内存数据库,默认情况下每一台redis服务器有16个数据库(关于数据库的设置,看下边代码),默认使用0号数据库,所有的操作都是对0号数据库的操作,关于redis数据库的存储结构,查看 第八章 Redis数据库结构与读写原理

设置数据库数量。默认为16个库,默认使用DB 0,可以使用"select 1"来选择一号数据库

注意:由于默认使用0号数据库,那么我们所做的所有的缓存操作都存在0号数据库上,

当你在1号数据库上去查找的时候,就查不到之前set过得缓存

若想将0号数据库上的缓存移动到1号数据库,可以使用"move key 1"

databases 16
memcached只是用了惰性删除,而Redis同时使用了惰性删除与定期删除,这也是二者的一个不同点(可以看做是redis优于memcached的一点)
对于惰性删除而言,并不是只有获取key的时候才会检查key是否过期,在某些设置key的方法上也会检查(eg.setnx key2 value2:该方法类似于memcached的add方法,如果设置的key2已经存在,那么该方法返回false,什么都不做;如果设置的key2不存在,那么该方法设置缓存key2-value2。假设调用此方法的时候,发现redis中已经存在了key2,但是该key2已经过期了,如果此时不执行删除操作的话,setnx方法将会直接返回false,也就是说此时并没有重新设置key2-value2成功,所以对于一定要在setnx执行之前,对key2进行过期检查)

<think>嗯,用户这次聚焦在Redis过期时间设置和过期策略上,看来ta正在深入理解缓存管理机制。此前对话中我已经解释了Redis同步机制,现在需要切换到数据淘汰维度。用户引用的资料相当全面,从过期策略类型到内存淘汰机制都有覆盖,说明ta做了预习。 用户可能是个后端开发者,正在设计缓存系统。ta特意提到“短信验证码”这种典型用例,说明需要实战指导。虽然引用资料完整,但三大策略的优缺点分散在不同条目里,需要我重新整合。定时删除的实时性优势(引用[2][3])和性能缺陷(引用[3])要对比着说,而惰性删除的内存泄漏风险(引用[2])正好能被定期删除弥补(引用[2][4])。 内存淘汰策略部分有个细节要注意:引用[5]提到默认策略是noeviction,但实际生产环境更常用volatile-lru。这个矛盾点需要解释清楚——开发环境默认防止数据丢失,线上则需主动淘汰。用户如果设置了过期时间却没配淘汰策略,可能踩坑。 接下来组织逻辑链:先讲如何设置过期时间(基础操作),再分析策略实现(技术原理),最后落地到配置建议(实战)。EXPIRE命令的毫秒级精度(引用[1])和TTL返回值(引用[4])这类API细节不能漏。对于时间单位混淆这个常见错误,要强调EXPIRE和PEXPIRE的区别。 用户没问但应该补充的是策略选择依据:比如金融交易类系统适合定时删除保证实时性,电商大促时用定期删除更稳妥。这些在“业务场景”段落用案例说明会更直观。最后的三个相关问题覆盖了配置(时间单位)、监控(淘汰统计)和设计(无过期数据管理),正好形成知识闭环。 </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、付费专栏及课程。

余额充值