redis(12):过期时间

一、命令介绍

在实际的开发中经常会遇到一些有时效的数据,比如限时优惠活动、缓存或验证码等, 过了一定的时间就需要删除这些数据。在关系数据库中一般需要额外的一个字段记录到期时 间,然后定期检测删除过期数据。

而在Redis中可以使用 EXPIRE命令设置一个键的过期时 间,到时间后Redis会自动删除它。

  • EXPIRE 命令的使用方法为 EXPIRE key seconds,其中 seconds 参数表示键的过期时 间,单位是秒。EXPIRE命令返回1表示设置成功,返回0则表示键不存在或设置失败;
    如要想让test:key键在10s后被删除:
    在这里插入图片描述

  • 如果想知道一个键还有多久的时间会被删除,可以使用TTL命令
    在这里插入图片描述

  • 如果没有设置过期时间,则exprie命令后返回-1

在2.6版中,无论键不存在还是键没有过期时间都会返回−1,直到2.8版后两种 情况才会分别返回−2(键不存在)和−1两种结果。

  • 如果想取消键的过期时间设置(即将键恢复成永久的),则可以使用PERSIST命令。如 果过期时间被成功清除则返回1;否则返回0(因为键不存在或键本来就是永久的):
    在这里插入图片描述
  • 除了PERSIST命令之外,使用SET或GETSET命令为键赋值也会同时清除键的过期时间;
  • 如果想要更精确的控制键 的过期时间应该使用 PEXPIRE命令,PEXPIRE命令与 EXPIRE的唯一区别是前者的时间单
    位是毫秒,即 PEXPIRE key 1000 与 EXPIRE key 1 等价。

二、实现访问频繁限制之一

为了减轻服务器的压力,需要限制每个用户(以IP计)一段时间的最 大访问量。与时间有关的操作很容易想到EXPIRE命令

例如要限制每分钟每个用户最多访问100个页面,设计key=rate:limiting:用户ip,每次用户访问则使用incr,同时设置过期时间为1分钟,用户每次访问页面,redis incr获取一个值,如果大于100,页面给出提示。如果时间到了1分钟,则key会被删除,进入下一次计算;

伪代码如下
1,判断key是否存在
2,如果key存在,则incr
3,设置过期时间
4,拿到incr结果判断是否 大于100

上述伪代码的23步骤存在一定文档,如果2执行完,3还没执行(即没有设置过期事情)那么key会永远存在,所以 用户访问总数限制到100,而非每分钟限制100;
所以可以用上redis事务,修改后伪代码如下

$isKeyExists = EXISTS rate.limiting:$IP 
if $isKeyExists is 1
	$times = INCR rate.limiting:$IP 
	if $times > 100 
		print 访问频率超过了限制,请稍后再试。 
	exit 
else 
	MULTI 
	INCR rate.limiting:$IP 
	EXPIRE $keyName, 60 
EXEC

三、实现访问频繁限制之二

上面的代码仍然有个问题:如果一个用户在一分钟的第一秒访问了一次博 客,在同一分钟的最后一秒访问了99次,又在下一分钟的第一秒访问了3次,这样的访问是 可以通过现在的访问频率限制的,但实际上该用户在2秒内访问了102次博客,这与每个用户 每分钟只能访问10次的限制差距较大。尽管这种情况比较极端,但是在一些场合中还是需要 粒度更小的控制方案。如果要精确地保证每分钟最多访问10次,需要记录下用户每次访问的 时间

在这里插入图片描述

因此对每个用户,我们使用一个列表类型的键来记录他最近100次访问博客的时间。一 旦键中的元素超过 100 个,就判断时间最早的元素距现在的时间是否小于 1分钟。如果是则表 示用户最近1分钟的访问次数超过了10次;如果不是就将现在的时间加入到列表中,同时把 最早的元素删除。
伪代码如下:

$listLength = LLEN rate.limiting:$IP
 if $listLength < 10 
	 LPUSH rate.limiting:$IP, now() 
 else 
	 $time = LINDEX rate.limiting:$IP, -1 
	 if now() - $time < 60 
	 	print 访问频率超过了限制,请稍后再试。
	  else 
	  	LPUSH rate.limiting:$IP, now()

四、实现缓存

为了提高网站的负载能力,常常需要将一些访问频率较高但是对CPU或IO资源消耗较大 的操作的结果缓存起来,并希望让这些缓存过一段时间自动过期。

比如教务网站要对全校所 有学生的各个科目的成绩汇总排名,并在首页上显示前10名的学生姓名,由于计算过程较耗 资源,所以可以将结果使用一个 Redis 的字符串键缓存起来。由于学生成绩总在不断地变化,需要每隔两个小时就重新计算一次排名,这可以通过给键设置过期时间的方式实现。每 次用户访问首页时程序先查询缓存键是否存在,如果存在则直接使用缓存的值;否则重新计 算排名并将计算结果赋值给该键并同时设置该键的过期时间为两个小时。

然而在一些内存不多的场合中,需要淘汰一些过期的key,具体的设置方法为:修改配置文件的maxmemory参数,限制Redis最大可用内存大小 (单位是字节),当超出了这个限制时Redis会依据maxmemory-policy参数指定的策略来删 除不需要的键直到Redis占用的内存小于指定内存

maxmemory-policy支持的规则下图所示。其中的LRU(Least Recently Used)算法 即“最近最少使用”,其认为最近最少使用的键在未来一段时间内也不会被用到,即当需要空间时这些键是可以被删除的。

在这里插入图片描述
如当maxmemory-policy设置为allkeys-lru时,一旦Redis占用的内存超过了限制值, Redis会不断地删除数据库中最近最少使用的键,直到占用的内存小于限制值。

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页