Redis过期

Redis过期

为什么设置过期?

1.因为内存是有限的,如果缓存中的所有数据都是一直保存的话,分分钟直接Out of memory。

2.有些场景需要设置过期时间:比如短信验证。

如果使用传统的数据库来处理的话,一般都是自己判断过期,这样更麻烦并且性能要差很多

如何设置过期?

Redis中除了字符串类型有自己独有设置过期时间的命令 setex 外,其他方法都需要依靠 expire 命令来设置过期时间 。另外, persist 命令可以移除一个键的过期时间

如何判断过期?

Redis 通过一个叫做过期字典(可以看作是hash表)来保存数据过期的时间

typedef struct redisDb {
    ...
    dict *dict;     //数据库键空间,保存着数据库中所有键值对
    dict *expires   // 过期字典,保存着键的过期时间
    ...
} redisDb;

举例:
有三个类型数据:List类型的alphabet ,Hash类型book,string类型message

alphabet对于值为string类型a,string类型b,string类型c

book对应值为string类型name,string类型author,string类型publicsher

message对应值为string类型的hello world

alphabet过期时间为long long类型1385877600000

在这里插入图片描述

过期删除策略

redis提供了以下三种删除策略,可以根据实际业务场景选择合适的删除策略

定时删除,惰性删除,定期删除,内存淘汰机制

  • 定时删除 对内存友好,对CPU不友好
    对内存是最友好的:通过定时器,定时删除策略可以保证过期键会尽快被删除,并释放过期键所占用的内存

    对 CPU 时间不友好:在过期键比较多的情况下,删除过期键可能会占用相当一部分 CPU 时间

  • 惰性删除 对内存不友好,对CPU友好
    对 CPU 时间最友好:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的键,这个策略不会在删除其他无关的过期键上花费任何 CPU 时间

    对内存是最不友好的:如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放,这可以看作是一种内存泄漏

  • 定期删除

    定期删除策略是前两种策略的一种折中:

    • 定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响
    • 此外,通过定期删除过期键,可以有效减少内存浪费
  • 内存淘汰机制

### Redis 过期 Key 的处理机制 Redis 中的过期 Key 主要通过两种方式进行处理:惰性删除和定期删除。 #### 惰性删除 当客户端尝试访问某个 Key 时,如果发现该 Key 已经过期,则会在返回结果之前将其删除。这种方式的优点是不会主动占用 CPU 资源去扫描和删除过期 Key,缺点是在高并发场景下可能会导致大量已过期但尚未被访问的 Key 占用内存资源[^1]。 ```python def lazy_deletion(key): if is_expired(key): # 判断key是否已经过期 delete_key(key) # 删除过期key ``` #### 定期删除 为了弥补惰性删除可能带来的内存浪费问题,Redis 实现了一种定时任务,在后台周期性地检查并删除部分过期 Key。这种机制的核心在于选取一定数量的数据库分片(database slots),从中随机抽取若干 Keys 并逐一判断它们是否需要被清除。虽然这种方法无法一次性彻底清理所有过期数据,但它能够在一定程度上缓解内存压力[^2]。 ```c void active_expire_cycle() { int dbs_per_call = REDIS_EXPIRE_DBS_PER_CALL; // 数据库轮询次数 while (dbs_per_call--) { int j; for (j = 0; j < REDIS_EXPIRE_SAMPLE_KEYS; j++) { // 抽样样本数 sds key = getRandomKey(); if (is_expired(key)) { server.db->expires[key]--; freeMemoryIfNeeded(); // 如果必要则释放内存 } } } } ``` 这两种方法各有优劣,实际应用中通常会结合使用以达到最佳效果。对于某些特殊需求的应用程序来说,还可以利用订阅发布模式配合 Lua 脚本等方式自定义更复杂的逻辑来应对业务层面的需求[^4]。 另外值得注意的是,在采用 LRU 或 LFU 等淘汰策略管理有限容量内的对象集合时,即使设置了合理的 TTL 值也不能完全避免因突发流量而导致缓存击穿的风险。因此建议开发者们根据实际情况合理规划存储结构以及预估峰值负载情况下的表现特性[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值