Redis(九):进阶篇 - 过期时间

过期时间

1、命令介绍

  EXPIRE命令的使用方法为

EXPIRE key seconds

  seconds参数表示键的过期时间,单位是秒。如设置key键的过期时间为20秒,即20秒后,key键自动被删除:

127.0.0.1:6379> get key
"333"
127.0.0.1:6379> expire key 20
(integer) 1
20秒后在设置过期时间
127.0.0.1:6379> expire key 20
(integer) 0
127.0.0.1:6379> get key
(nil)

  EXPIRE 命令返回1表示设置成功,返回0表键不存在或设置失败。
  使用TTL命令可以知道一个键还有多久时间会被删除。返回值是键的剩余时间(单位是秒):

127.0.0.1:6379> set key 111
OK
127.0.0.1:6379> expire key 10
(integer) 1
127.0.0.1:6379> ttl key
(integer) 7
127.0.0.1:6379> ttl key
(integer) 6
127.0.0.1:6379> ttl key
(integer) 2
127.0.0.1:6379> ttl key
(integer) -2

  10秒后key键被删除。当键不存在时,命令会返回-2;若键没有过期时间,则返回-1;

127.0.0.1:6379> set key 111
OK
127.0.0.1:6379> ttl key
(integer) -1

版本差异
在2.6版本中,无论键不存在还是键没有过期时间都会返回-1,知道2.8版后两种情况才会分别返回-2和-1两种结果。

  取消键的过期时间设置(即将键恢复成永久的),可以使用PERSIST key命令,过期时间被成功清楚返回1,否则返回0(因为键不存在或键本来就是永久的):

127.0.0.1:6379> persist key
(integer) 0
127.0.0.1:6379> expire key 100
(integer) 1
127.0.0.1:6379> ttl key
(integer) 96
127.0.0.1:6379> persist key
(integer) 1
127.0.0.1:6379> ttl key
(integer) -1

  使用SET或GETSET命令为键赋值也可以清除键的过期时间:

127.0.0.1:6379> expire key 30
(integer) 1
127.0.0.1:6379> ttl key
(integer) 27
127.0.0.1:6379> set key 3
OK
127.0.0.1:6379> ttl key
(integer) -1

  使用EXPIRE命令会重新设置键的过期时间:

127.0.0.1:6379> expire key 30
(integer) 1
127.0.0.1:6379> ttl key
(integer) 21
127.0.0.1:6379> expire key 30
(integer) 1
127.0.0.1:6379> ttl key
(integer) 29

  EXPIRE命令的seconds参数必须是整数,所以最小单位是1秒。如果想要更精确的控制键的过期时间应该使用PEXPIRE命令,PEXPIRE命令与EXPIRE的唯一区别是前者的时间单位是毫秒,即PEXPIRE key 1000与EXPIRE key 1等价。使用PTTL命令以毫秒为单位返回键的剩余时间。

提示
如果使用WATCH命令监测了一个拥有过期时间的键,该键时间到期自动删除并不会被WATCH命令认为该键被改变。

  另外,EXPIREAT和PEXPIREAT命令的时间是UNIX时间。PEXPIREAT的单位是毫秒 。

2、应用

2.1、实现访问频率

  如一个网站,限制每分钟每个用户最多只能访问100个页面,思路是对每个用户使用一个名为 rate:limiting:用户ID 的字符串类型键,每次用户访问则使用INCR命令递增该键的键值,如果递增后的值是1(第一个访问页面),则同时还要设置该键的过期时间为1分钟。这样每次用户访问页面时都读取该键的键值,如果超过了100就表明该用户的访问频率超过了限制,需要提示用户稍后访问。该键每分钟会自动被删除,所以下一分钟用户的访问次数又会重新计算,也就达到了限制访问频率的目的。

2.2、实现缓存

  为了提高系统的负载能力,常常需要将一些访问频率较高但是对CPU或IO资源消耗较大的操作的结果缓存起来,并希望让这些缓存过一段时间自动过期。
  如一个学校教务网站要对正在参加学校组织的计算机编程比赛的所有学生的成绩汇总排名,并在首页上显示前10名的学生姓名,由于计算过程较耗资源,所以可以将结果使用一个Redis的字符串键缓存起来。由于学生的成绩总在不断地变化,需要每隔10分钟就重新计算一次排名。这可以通过给键设置过期时间的方式实现。每次用户访问首页时程序先查询缓存键是否存在,如果存在则直接使用缓存的值;否则重新计算排名并将计算结果赋值给该键并同时设置该键的过期时间为两个小时。

  然而在一些场合中这种方法并不能满足需要。当服务器内存有限时,如果大量地使用缓存键且过期时间设置的过长就会导致Redis占满内存;另一方面如果为了防止Redis占用内存过大而将缓存键的过期时间设得太短,就可能导致缓存命中率过低并且大量内存白白地闲置。实际开发中会发现很难为缓存键设置合理的过期时间,为此可以限制Redis能够使用的最大内存,并让Redis按照一定的规则淘汰不需要的缓存键,这种方式只将Redis用作缓存系统时非常实用。
  具体设置方法为:修改配置文件的maxmemory参数,限制Redis最大可用内存大小(单位是字节),当超过了这个限制时,Redis会依据maxmemory-policy参数指定的策略来删除不需要的键知道Redis占用的内存小于指定内存。

  maxmemory-policy支持的规则如下表所示:

规则说明
volatile-lru使用LRU算法删除一个键(只对设置了过期时间的键)
allkeys-lru使用LRU算法删除一个键(全部的键)
volatile-random随机删除一个键(只对设置了过期时间的键)
allkeys-random随机删除一个键(全部的键)
volatile-ttl删除过期时间最近的一个键
noeviction不删除键,只返回错误

  LRU(Least Recently Used)算法即“最近最少使用”,其认为最近最少使用的键在未来一段时间内也不会被用到,即当需要空间时这些键是可以被删除的。

  如当maxmemory-policy设置为allkeys-lru时,一旦Redis占用的内存超过了限制值,Redis会不断地删除数据库中最近最少使用的键,知道占用的内存小于限制值。

一般的经验规则:

  使用allkeys-lru策略:当你希望你的请求符合一个幂定律分布,也就是说,你希望部分的子集元素将比其它其它元素被访问的更多。如果你不确定选择什么,这是个很好的选择。.
  使用allkeys-random:如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常(所有元素被访问的概率都差不多)。
  使用volatile-ttl:如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期。


author:su1573
鄙人记录生活点滴,学习并分享,请多指教!!!
如需交流,请联系 sph1573@163.com,鄙人看到会及时回复

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ssy03092919

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

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

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

打赏作者

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

抵扣说明:

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

余额充值