Redis面试题分享二十七:Redis key 的过期时间和永久有效分别怎么设置?

本文详细介绍了Redis中设置和管理键过期时间的多种策略,包括EXPIRE、PEXPIREAT等,以及如何处理过期键,如惰性删除和定期删除。同时涵盖了主从服务器删除过期键的机制,以及与Quartz的相关解决方案。
摘要由CSDN通过智能技术生成

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

一、有效时间设置

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

四种处理策略

  • EXPIRE 将key的生存时间设置为ttl秒
  • PEXPIRE 将key的生成时间设置为ttl毫秒
  • EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
  • PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳

其实以上几种处理方式都是根据PEXPIREAT来实现的,设置生存时间的时候是redis内部计算好时间之后在内存处理的,最终的处理都会转向PEXPIREAT。

1、2两种方式是设置一个过期的时间段,就是咱们处理验证码最常用的策略,设置三分钟或五分钟后失效,把分钟数转换成秒或毫秒存储到redis中。

3、4两种方式是指定一个过期的时间 ,比如优惠券的过期时间是某年某月某日,只是单位不一样。

二、永久有效设置

为了避免内存过度消耗,Redis并不支持完全的永久有效,但我们可以设置一个非常大的过期时间,使得 Redis key 看上去永久有效。例如:

# 设置key为value,并设置过期时间为100年redis> SET key1 value1OKredis> EXPIRE key1 3153600000(integer) 1

这种设置的优点是可以保证 key 一直有效,避免因时间设置不当而导致的数据丢失。但是,需要注意的是,由于 Redis 中的 key 会消耗内存,大量设置永久有效的 key 会导致内存过度占用,从而造成 Redis 性能下降。

以上是 Redis key 的过期时间和永久有效的设置方法和示例,不同的业务场景需要根据实际需求来选择合适的设置方式。

三、过期键的判定

通过过期字典,程序可以用以下步骤检查一个给定键是否过期:

1)检查给定键是否存在于过期字典:如果存在,那么取得键的过期时间。

2)检查当前UNIX时间戳是否大于键的过期时间:如果是的话,那么键已经过期;否则的话,键未过期。

四、计算并返回键剩余生存时间

TTL命令以秒为单位返回键的剩余生存时间,而PTTL命令则以毫秒为单位返回键的剩余生存时间:

127.0.0.1:6379> expire key 1000

(integer) 1

127.0.0.1:6379> ttl key

(integer) 997

127.0.0.1:6379> pttl key

(integer) 993434

127.0.0.1:6379>

五、移除过期时间

使用PERSIST命令可以移除一个键的过期时间。

127.0.0.1:6379> set key value

OK

127.0.0.1:6379> expire key 1000

(integer) 1

127.0.0.1:6379> ttl key

(integer) 992

127.0.0.1:6379> persist key

(integer) 1

127.0.0.1:6379> ttl key

(integer) -1

127.0.0.1:6379>

PERSIST命令就是PEXPIREAT命令的反操作:PERSIST命令在过期字典中查找给定的键,并解除键和值(过期时间)在过期字典中的关联。

六、过期处理

过期键的处理就是把过期键删除,这里的操作主要是针对过期字段处理的。

Redis中有三种处理策略:定时删除、惰性删除和定期删除。

  1. 定时删除:在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作。不过这种处理方式是即时的,不管这个时间内有多少过期键,不管服务器现在的运行状况,都会立马执行,所以对CPU不是很友好。
  2. 惰性删除:惰性删除策略不会在键过期的时候立马删除,而是当外部指令获取这个键的时候才会主动删除。处理过程为:接收get执行、判断是否过期(这里按过期判断)、执行删除操作、返回nil(空)。
  3. 定期删除:定期删除是设置一个时间间隔,每个时间段都会检测是否有过期键,如果有执行删除操作。这个概念应该很好理解。

看完上面三种策略后可以得出以下结论:

1)、3为主动删除,2为被动删除。

1是实时执行的,对CPU不是很友好,但是这在最大程度上释放了内存,所以这种方式算是一种内存优先优化策略。

2)、2为被动删除,所以过期键应该会存在一定的时间,这样就使得过期键不会被立马删除,仍然占用着内存。但是惰性删除的时候一般是单个删除,相对来说对CPU是友好的。

定期键这种删除策略是一种让人很蛋疼的策略,它既有避免1、2两种策略劣势的可能,也有同时发生1、2两种策略劣势的可能。如果定期删除执行的过于频繁就可能会演变成定时删除,如果执行的过少就有可能造成过多过期键未被删除而占用过多内存,如果时间的设置不是太好,既可能占用过多内存又同时对CPU产生不好的影响。所以。使用定期删除的时候一定要把握好这个删除的时间点。存在即为合理,既然开发的时候有这种策略,就说明定期删除还是有他的优势的,具体大家可以自己琢磨。

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

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

RDB:

1. 主服务器模式运行在载入RDB文件时,程序会检查文件中的键,只会加载未过期的,过期的会被忽略,所以RDB模式下过期键不会对主服务器产生影响。

2. 从服务器运行载入RDB文件时,会载入所有键,包括过期和未过期。当主服务器进行数据同步的时候,从服务器的数据会被清空,所以RDB文件的过期键一般不会对从服务器产生影响。

AOF:

AOF文件不会受过期键的影响。如果有过期键未被删除,会执行以下动作:

客户端请求时(过期键):

1.从数据库充删除被访问的过期键;

2.追加一条DEL 命令到AOF文件;

3.向执行请求的客户端回复nil(空)。

复制:

1.主服务器删除过期键之后,向从服务器发送一条DEL指令,告知删除该过期键。

2.从服务器接收到get指令的时候不会对过期键进行处理,只会当做未过期键一样返回。(为了保持主从服务器数据的一致性)

3.从服务器只有接到主服务器发送的DEL指令后才会删除过期键。

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

八、补充知识

redis缓存数据需要指定缓存有效时间范围段的多个解决方案 Calendar+quartz

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值