对于Redis中设置了过期时间的Key,你需要知道这些内容「建议收藏」

对于Redis中设置了过期时间的Key,你需要知道这些内容

大家好,又见面了,我是全栈君。

熟悉Redis的同学应该知道,Redis的每个Key都可以设置一个过期时间,当达到过期时间的时候,这个key就会被自动删除。

在为key设置过期时间需要注意的事项

1、 DEL/SET/GETSET等命令会清除过期时间

在使用DEL、SET、GETSET等会覆盖key对应value的命令操作一个设置了过期时间的key的时候,会导致对应的key的过期时间被清除。

//设置mykey的过期时间为300s
127.0.0.1:6379> set mykey hello ex 300
OK
//查看过期时间
127.0.0.1:6379> ttl mykey
(integer) 294
//使用set命令覆盖mykey的内容
127.0.0.1:6379> set mykey olleh
OK
//过期时间被清除
127.0.0.1:6379> ttl mykey
(integer) -1

2、INCR/LPUSH/HSET等命令则不会清除过期时间

而在使用INCR/LPUSH/HSET这种只是修改一个key的value,而不是覆盖整个value的命令,则不会清除key的过期时间。 

INCR

//设置incr_key的过期时间为300s
127.0.0.1:6379> set incr_key 1 ex 300
OK
127.0.0.1:6379> ttl incr_key
(integer) 291
//进行自增操作
127.0.0.1:6379> incr incr_key
(integer) 2
127.0.0.1:6379> get incr_key
"2"
//查询过期时间,发现过期时间没有被清除
127.0.0.1:6379> ttl incr_key
(integer) 277

LPUSH

//新增一个list类型的key,并添加一个为1的值
127.0.0.1:6379> LPUSH list 1
(integer) 1
//为list设置300s的过期时间
127.0.0.1:6379> expire list 300
(integer) 1
//查看过期时间
127.0.0.1:6379> ttl list
(integer) 292
//往list里面添加值2
127.0.0.1:6379> lpush list 2
(integer) 2
//查看list的所有值
127.0.0.1:6379> lrange list 0 1
1) "2"
2) "1"
//能看到往list里面添加值并没有使过期时间清除
127.0.0.1:6379> ttl list
(integer) 252

3、PERSIST命令会清除过期时间

当使用PERSIST命令将一个设置了过期时间的key转变成一个持久化的key的时候,也会清除过期时间。

127.0.0.1:6379> set persist_key haha ex 300
OK
127.0.0.1:6379> ttl persist_key
(integer) 296
//将key变为持久化的
127.0.0.1:6379> persist persist_key
(integer) 1
//过期时间被清除
127.0.0.1:6379> ttl persist_key
(integer) -1

4、使用RENAME命令,老key的过期时间将会转到新key上

在使用例如:RENAME KEY_A KEY_B命令将KEY_A重命名为KEY_B,不管KEY_B有没有设置过期时间,新的key KEY_B将会继承KEY_A的所有特性。

//设置key_a的过期时间为300s
127.0.0.1:6379> set key_a value_a ex 300
OK
//设置key_b的过期时间为600s
127.0.0.1:6379> set key_b value_b ex 600
OK
127.0.0.1:6379> ttl key_a
(integer) 279
127.0.0.1:6379> ttl key_b
(integer) 591
//将key_a重命名为key_b
127.0.0.1:6379> rename key_a key_b
OK
//新的key_b继承了key_a的过期时间
127.0.0.1:6379> ttl key_b
(integer) 248

这里篇幅有限,我就不一一将key_a重命名到key_b的各个情况列出来,大家可以在自己电脑上试一下key_a设置了过期时间,key_b没设置过期时间这种情况。

5、使用EXPIRE/PEXPIRE设置的过期时间为负数或者使用EXPIREAT/PEXPIREAT设置过期时间戳为过去的时间会导致key被删除

EXPIRE:

127.0.0.1:6379> set key_1 value_1
OK
127.0.0.1:6379> get key_1
"value_1"
//设置过期时间为-1
127.0.0.1:6379> expire key_1 -1
(integer) 1
//发现key被删除
127.0.0.1:6379> get key_1
(nil)

EXPIREAT:

127.0.0.1:6379> set key_2 value_2
OK
127.0.0.1:6379> get key_2
"value_2"
//设置的时间戳为过去的时间
127.0.0.1:6379> expireat key_2 10000
(integer) 1
//key被删除
127.0.0.1:6379> get key_2
(nil)

6、EXPIRE命令可以更新过期时间

对一个已经设置了过期时间的key使用expire命令,可以更新其过期时间。

//设置key_1的过期时间为100s
127.0.0.1:6379> set key_1 value_1 ex 100
OK
127.0.0.1:6379> ttl key_1
(integer) 95
//更新key_1的过期时间为300s
127.0.0.1:6379> expire key_1 300
(integer) 1
127.0.0.1:6379> ttl key_1
(integer) 295

在Redis2.1.3以下的版本中,使用expire命令更新一个已经设置了过期时间的key的过期时间会失败。并且对一个设置了过期时间的key使用LPUSH/HSET等命令修改其value的时候,会导致Redis删除该key。

Redis的过期策略

那你有没有想过一个问题,Redis里面如果有大量的key,怎样才能高效的找出过期的key并将其删除呢,难道是遍历每一个key吗?假如同一时期过期的key非常多,Redis会不会因为一直处理过期事件,而导致读写指令的卡顿。

这里说明一下,Redis是单线程的,所以一些耗时的操作会导致Redis卡顿,比如当Redis数据量特别大的时候,使用keys * 命令列出所有的key。

实际上Redis使用懒惰删除+定期删除相结合的方式处理过期的key。

懒惰删除

所谓懒惰删除就是在客户端访问该key的时候,redis会对key的过期时间进行检查,如果过期了就立即删除。

这种方式看似很完美,在访问的时候检查key的过期时间,不会占用太多的额外CPU资源。但是如果一个key已经过期了,如果长时间没有被访问,那么这个key就会一直存留在内存之中,严重消耗了内存资源。

定期删除

定期删除的原理是,Redis会将所有设置了过期时间的key放入一个字典中,然后每隔一段时间从字典中随机一些key检查过期时间并删除已过期的key。

Redis默认每秒进行10次过期扫描:

  1. 从过期字典中随机20个key

  2. 删除这20个key中已过期的

  3. 如果超过25%的key过期,则重复第一步

同时,为了保证不出现循环过度的情况,Redis还设置了扫描的时间上限,默认不会超过25ms.

往日精选文章

最中肯的Redis规范全在这了

Redis 高级面试题 学会这些还怕进不了大厂?

Redis中缓存雪崩、缓存穿透等问题的解决方案

掌握Redis主从复制、哨兵、Cluster三种集群模式

2020 年最新版 68 道Redis面试题,收藏起来备用!

对于Redis中设置了过期时间的Key,你需要知道这些内容「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111789.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • eagle-eye介绍

    eagle-eye介绍简介淘宝现在是一个由很多个应用集群组成的非常复杂的分布式系统。这些应用里面主要有处理用户请求的前端系统和有提供服务的后端系统等。这些应用之间一般有RPC调用和异步消息通讯两种手段,RPC调用会产生一层调一层的嵌套,一个消息发布出来更会被多个应用消费,另外,应用还会访问分库分表的数据库、缓存、存储等后端,以及调用其他外部系统如支付、物流、机彩票等。请试想一下,现在淘宝一个买家点击下单按…

    2022年8月16日
    7
  • 工作流入门教程(flowable框架)

    工作流入门教程(flowable框架)最近有一段时间没写博客了,本来打算写写对于工作流的心得,但是工作时间比较饱和只好延后。最初接触工作流是上一家公司工作,具体我不透露哪家公司,只是感受到人情冷暖,或许公司都是这样,当你的价值被用完了也就是你走人的时候。好了,废话不多说,我们直接进入主题。前言对于框架的选型,我推荐使用flowable框架,在最初的项目选型是选择activiti的,但是深入去了解框架的时候发现activiti还是有一些坑的,而flowable正是activiti框架的修正版,据了解flowable的背景是activiti原班

    2022年5月21日
    1.8K
  • onResume的作用

    onResume的作用描述:今天在做一个功能的时候,从Aactivity跳到Bactivity。由于Bactivity的操作,影响了Aactivity的数据,所以再回到A的时候,需要A能够进行刷新操作。但是默认跳回去的时候,A界面还是上次那个。解决方案:重写Aactivity的onResume()方法,在onResume()方面里进行刷新操作。因为按照activity的生命周期模型,当activ

    2022年6月2日
    59
  • C#获取进程的主窗口句柄「建议收藏」

    C#获取进程的主窗口句柄「建议收藏」publicclassUser32API{  privatestaticHashtableprocessWnd=null;  publicdelegateboolWNDENUMPROC(IntPtrhwnd,uintlParam);  staticUser32API()  {    if(processWnd==nu

    2022年7月14日
    19
  • 电信光猫改桥接还在苦苦激活成功教程超级密码吗?

    电信光猫改桥接还在苦苦激活成功教程超级密码吗?电信光猫路由改桥接,不同的地区有不通的方法。比较幸运的地区和终端,有通用的超级密码。但是不幸的地区,就需要通过激活成功教程这个超级密码。我就属于比较不幸的地区,遇到不幸的终端:天翼网关TEWA-708G。然后按照网上大神的激活成功教程方法:先是普通用户登录,然后通过备份的方式,将备份文件考出,再通过电脑上的网页源码查看软件找到超级用户的密码。里面当然也有宽带的用户名和密码。通过多方努力,我成功了。然后开心的准备给家里买个新的路由器,准备换上。这中间大概隔了一两周的时间。悲剧发生了。。。。。。光猫的版本升级了,这个漏洞被电信

    2022年10月8日
    0
  • pycharm激活码永久(注册激活)

    (pycharm激活码永久)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~4D5UJRVIF9-eyJsaWNlb…

    2022年3月30日
    56

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号