Redis-Key的生存时间

在实际开发过程中,经常会遇到一些有实效性的数据,比如限时优惠、缓存、验证码等等,过了一段时间后就应该删除这些数据。如果用关系型数据库,那么就需要在表中增加一个字段存储实效时间,然后定时轮询该字段并判断删除。而在redis中,可以使用expire命令给key设置有效时间来实现这个需求。

操作命令

expire key seconds    #设置key的有效时间  单位为秒
ttl key               #获取key的剩余有效时间
persist key           #设置有时效性的key为持久key

注意,对有实效性的key使用set会字段取消实效设置,变成持久key。

示例:

127.0.0.1:6379> set session:a34d zhangsan
OK
127.0.0.1:6379> expire session:a34d 20
(integer) 1
127.0.0.1:6379> ttl session:a34d
(integer) 2
127.0.0.1:6379> ttl session:a34d
(integer) -2
127.0.0.1:6379> get session:a34d
(nil)
127.0.0.1:6379> set session:a34d 40
OK
127.0.0.1:6379> ttl session:a34d
(integer) -1
127.0.0.1:6379> expire session:a34d 30
(integer) 1
127.0.0.1:6379> ttl session:a34d
(integer) 22
127.0.0.1:6379> persist session:a34d
(integer) 1
127.0.0.1:6379> ttl session:a34d
(integer) -1
127.0.0.1:6379> get session:a34d
"40"
127.0.0.1:6379> 

实践

1)限制具体IP在某个时段内的访问次数
有时,出于对网站的保护,我们需要对同一个ip的访问频率做出限制,以防止黑客攻击、网络爬虫给网站造成负载过大甚至崩溃。

对于这个需求,利用具有时效性的key就可以很好的解决。例如,限制每个用户每分钟最多访问网站100次,对应的思路就是:

对每一个用户创建一个名为rate.limiting:userip的键
设置改键的生存时间为1分钟
每次用户访问时,首先读取这个键的键值
判断是否超过100
使用incr命令将该键值+1
有效时间到,键自动删除
用户再访问时,重建该键,循环往复

伪代码如下:

$isKeyExists = exists rate.limiting:$ip
#如果存在
if $isKeyExists is 1
    $times = incr rate.limiting:$ip
    if $times > 100
        print "post limit"
        exit
else
    incr rate.limiting:$ip   #自动创建并初始值1
    expire rate.limiting:$ip 60

上面的代码有一个非常严重的潜在问题,如果成行在运行完inr rate.limiting:$ip后因为某种原因退出了,那么这个key就没有被设置有效时间,此后,这个ip在访问网站时,就会跳过访问频率的限制。

我们可以利用reids提供的事务能力对上面的代码进行改写

$isKeyExists = exists rate.limiting:$ip
#如果存在
if $isKeyExists is 1
    $times = incr rate.limiting:$ip
    if $times > 100
        print "post limit"
        exit
else
    mulit
        incr rate.limiting:$ip   #自动创建并初始值1
        expire rate.limiting:$ip 60
    exec

你可能感兴趣的:(Code-Redis)