redis设置redis获取过期时间间后取值失败,不设置redis获取过期时间间能取值,哪里出问题了


本文对redis的过期处理机制做个简单嘚概述让大家有个基本的认识。

Redis中有个设置时间过期的功能即对存储在redis数据库中的值可以设置一个redis获取过期时间间。作为一个缓存数據库这是非常实用的。如我们一般项目中的token或者一些登录信息尤其是短信验证码都是有时间限制的,按照传统的数据库处理方式一般都是自己判断过期,这样无疑会严重影响项目性能

redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的囿效时间Expires字典保存了所有键的redis获取过期时间间,Expires也被称为过期字段 

其实以上几种处理方式都是根据PEXPIREAT来实现的,设置生存时间的时候是redis內部计算好时间之后在内存处理的最终的处理都会转向PEXPIREAT。 
1、2两种方式是设置一个过期的时间段就是咱们处理验证码最常用的策略,设置三分钟或五分钟后失效把分钟数转换成秒或毫秒存储到redis中。 
3、4两种方式是指定一个过期的时间 比如优惠券的redis获取过期时间间是某年某月某日,只是单位不一样

过期键的处理就是把过期键删除,这里的操作主要是针对过期字段处理的 
Redis中有三种处理策略:定时删除、惰性删除和定期删除。

定时删除:在设置键的redis获取过期时间间的时候创建一个定时器当redis获取过期时间间到的时候立马执行删除操作。不過这种处理方式是即时的不管这个时间内有多少过期键,不管服务器现在的运行状况都会立马执行,所以对CPU不是很友好
惰性删除:惰性删除策略不会在键过期的时候立马删除,而是当外部指令获取这个键的时候才会主动删除处理过程为:接收get执行、判断是否过期(這里按过期判断)、执行删除操作、返回nil(空)。
定期删除:定期删除是设置一个时间间隔每个时间段都会检测是否有过期键,如果有執行删除操作这个概念应该很好理解。
看完上面三种策略后可以得出以下结论: 
4. 1、3为主动删除2为被动删除。 
5. 1是实时执行的对CPU不是很伖好,但是这在最大程度上释放了内存所以这种方式算是一种内存优先优化策略。 
6. 2、3为被动删除所以过期键应该会存在一定的时间,這样就使得过期键不会被立马删除仍然占用着内存。但是惰性删除的时候一般是单个删除相对来说对CPU是友好的。 
定期键这种删除策略昰一种让人很蛋疼的策略它既有避免1、2两种策略劣势的可能,也有同时发生1、2两种策略劣势的可能如果定期删除执行的过于频繁就可能会演变成定时删除,如果执行的过少就有可能造成过多过期键未被删除而占用过多内存如果时间的设置不是太好,既可能占用过多内存又同时对CPU产生不好的影响所以。使用定期删除的时候一定要把握好这个删除的时间点存在即为合理,既然开发的时候有这种策略僦说明定期删除还是有他的优势的,具体大家可以自己琢磨

三、主从服务器删除过期键处理

参考书上说的有三种:RDB持久化、AOF持久化和复淛功能。

1. 主服务器模式运行在载入RDB文件时程序会检查文件中的键,只会加载未过期的过期的会被忽略,所以RDB模式下过期键不会对主服務器产生影响 
2. 从服务器运行载入RDB文件时,会载入所有键包括过期和未过期。当主服务器进行数据同步的时候从服务器的数据会被清涳,所以RDB文件的过期键一般不会对从服务器产生影响

AOF文件不会受过期键的影响。如果有过期键未被删除会执行以下动作: 
客户端请求時(过期键):

从数据库充删除被访问的过期键;
追加一条DEL 命令到AOF文件;
向执行请求的客户端回复nil(空)。

  1. 主服务器删除过期键之后向從服务器发送一条DEL指令,告知删除该过期键
  2. 从服务器接收到get指令的时候不会对过期键进行处理,只会当做未过期键一样返回(为了保持主从服务器数据的一致性)
  3. 从服务器只有接到主服务器发送的DEL指令后才会删除过期键

参考书籍:《Redis设计与实现》黄健宏著

}

一.Redis过期键删除策略

A.定时删除(不采用)

设置键的redis获取过期时间间时创建一个 Timer ,当redis获取过期时间间到临时立刻删除键。
内存友好型策略一旦键过期,就会被删除并釋放所占用的内存,Cpu 不友好当一批数量比较多的键redis获取过期时间,正好遇上Cpu 紧张的时段这时候需要的是Cpu处理能力,而不是内存显然 Cpu 時间用在删除过期键上,会对服务器的响应时间和吞吐量造成影响另外当前 Redis 时间事件(无序链表O(N))无法高效处理大量时间事件,所以定時删除并不是一种好的定时删除策略

不管过期的键,在这种策略下当键在键空间中被取出时,首先检查取出的键是否过期若过期删除该键,否则返回该键。
很明显惰性删除依赖过期键的被动访问,对于内存不友好如果一些键长期没有被访问,会造成内存泄露(垃圾数据占用内存)我们知道,Redis是依赖内存的所以惰性删除也不是一个好的策略。

由定时删除算法定期的去检查一定的数据库,删除一定的过期键
通过合理的删除操作执行的时长和频率,达到合理的删除过期键

其实,redis采用的是定期删除+惰性删除策略

B.为什么不用萣时删除策略?

定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放但是十分消耗CPU资源。在大并发请求下CPU要将时间应鼡在处理请求,而不是删除key,因此没有采用这一策略.

C.定期删除+惰性删除是如何工作的呢?

定期删除redis默认每个100ms检查,是否有过期的key,有过期key则删除需要说明的是,redis不是每个100ms将所有的key检查一次而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)因此,如果只采用定期删除策略会导致很多key到时间没有删除。
于是惰性删除派上用场。也就是说在你获取某个key的时候redis会检查一下,这个key如果设置了redis获取过期時间间那么是否过期了如果过期了此时就会删除。

D.采用定期删除+惰性删除就没其他问题了么?

不是的如果定期删除没删除key。然后你也没即时去请求key也就是说惰性删除也没生效。这样redis的内存会越来越高。那么就应该采用内存淘汰机制

二.Redis内存淘汰机制

三.其他模块对淘汰鍵的处理

执行 SAVE 或 BGSAVE 时 ,数据库键空间中的过期键不会被保存在RDB文件中

Master 载入RDB时文件中的未过期的键会被正常载入,过期键则会被忽略
Slave 载入 RDB 時,文件中的所有键都会被载入当同步进行时,会和Master 保持一致

数据库键空间的过期键的过期但并未被删除释放的状态会被正常记录到 AOF 攵件中
当过期键发生释放删除时,DEL 也会被同步到 AOF 文件中去

4.重新生成 AOF文件时

执行 BGREWRITEAOF 时 ,数据库键中过期的键不会被记录到 AOF 文件中

Master 删除过期 Key 之後会向所有 Slave 服务器发送一个 DEL命令,从服务器收到之后会删除这些 Key。
Slave 在被动的读取过期键时不会做出操作,而是继续返回该键只有當Master 发送 DEL 通知来,才会删除过期键这是统一、中心化的键删除策略,保证主从服务器的数据一致性

}

我要回帖

更多关于 redis获取过期时间 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信