李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
【转载】Redis设置过期时间注意事项
Leefs
2020-09-28 PM
2691℃
0条
# 【转载】Redis设置过期时间注意事项 ### 前言 用过Redis的应该知道,Redis的每个key都可以设置一个过期时间,当达到过期时间的时候,这个key就会被自动删除。但是有时候我们发现设置过过期时间的key并没有我们设置的时间点失效。这里我们来详细聊一下有关过期时间的问题。 ### 一、设置过期时间需要注意的事项 **1、DEL/SET/GETSET等命令会清除过期时间** 在使用DEL、SET、GETSET等会覆盖key对应value的命令操作一个设置了过期时间的key的时候,会导致对应的key的过期时间被清除。 ```java //设置mykey的过期时间为500s 127.0.0.1:6379> set tkey test ex 500 OK //查看过期时间 127.0.0.1:6379> ttl tkey (integer) 294 //使用set命令覆盖tkey的内容 127.0.0.1:6379> set tkey updatetest OK //过期时间被清除 127.0.0.1:6379> ttl tkey (integer) -1 ``` **2、INCR/LPUSH/HSET等命令则不会清除过期时间** 而在使用INCR/LPUSH/HSET这种只是修改一个key的value,而不是覆盖整个value的命令,则不会清除key的过期时间。 **INCR:** ```java //设置incr_key的过期时间为500s 127.0.0.1:6379> set incr_key 1 ex 500 OK 127.0.0.1:6379> ttl incr_key (integer) 390 //进行自增操作 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) 312 ``` **LPUSH:** ```java //新增一个list类型的key,并添加一个为1的值 127.0.0.1:6379> LPUSH list 1 (integer) 1 //为list设置500s的过期时间 127.0.0.1:6379> expire list 500 (integer) 1 //查看过期时间 127.0.0.1:6379> ttl list (integer) 392 //往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) 352 ``` **3、PERSIST命令会清除过期时间** 当使用PERSIST命令将一个设置了过期时间的key转变成一个持久化的key的时候,也会清除过期时间。 ```java 127.0.0.1:6379> set persist_key hello ex 400 OK 127.0.0.1:6379> ttl persist_key (integer) 396 //将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_1 KEY_2命令将KEY_1重命名为KEY_2,不管KEY_1有没有设置过期时间,新的key KEY_2将会继承KEY_1的所有特性。 ```java //设置key_1的过期时间为400s 127.0.0.1:6379> set key_1 value_1 ex 400 OK //设置key_2的过期时间为500s 127.0.0.1:6379> set key_2 value_2 ex 500 OK 127.0.0.1:6379> ttl key_1 (integer) 379 127.0.0.1:6379> ttl key_2 (integer) 391 //将key_1重命名为key_2 127.0.0.1:6379> rename key_1 key_2 OK //新的key_1继承了key_2的过期时间 127.0.0.1:6379> ttl key_2 (integer) 348 ``` **5、使用EXPIRE/PEXPIRE设置的过期时间为负数或者使用EXPIREAT/PEXPIREAT** **设置过期时间戳为过去的时间会导致key被删除** **EXPIRE:** ```java 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:** ```java 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命令,可以更新其过期时间。 ```java //设置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非常多,Redis会不会因为一直处理过期事件,而导致读写指令的卡顿。 因为Redis是单线程的,所以一些耗时的操作会导致Redis卡顿,比如当Redis数据量特别大的时候,使用keys * 命令列出所有的key。 实际上Redis使用懒惰删除+定期删除相结合的方式处理过期的key。 **1.懒惰删除** 懒惰删除就是在客户端访问该key的时候,redis会对key的过期时间进行检查,如果过期了就立即删除。 这种方式看似很完美,在访问的时候检查key的过期时间,不会占用太多的额外CPU资源。但是如果一个key已经过期了,如果长时间没有被访问,那么这个key就会一直存留在内存之中,严重消耗了内存资源。 **2.定期删除** 定期删除的原理是,Redis会将所有设置了过期时间的key放入一个字典中,然后每隔一段时间从字典中随机一些key检查过期时间并删除已过期的key。 Redis默认每秒进行10次过期扫描: (1)从过期字典中随机20个key (2)删除这20个key中已过期的 (3)如果超过25%的key过期,则重复第一步 同时,为了保证不出现循环过度的情况,Redis还设置了扫描的时间上限,默认不会超过25ms。 *附:[原文链接地址](https://blog.csdn.net/cyb_123/article/details/107799058?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-2-107799058.nonecase&utm_term=redis%20%E8%87%AA%E5%A2%9E%20%E8%BF%87%E6%9C%9F%E6%97%B6%E9%97%B4&spm=1000.2123.3001.4430)*
标签:
Java
,
Redis
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/922.html
上一篇
【转载】RabbitMQ和Kafka区别
下一篇
Java反射技术简介
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Hive
SpringCloudAlibaba
Tomcat
Flume
Livy
Jquery
Java阻塞队列
栈
GET和POST
NIO
Java编程思想
序列化和反序列化
Beego
DataX
CentOS
Nacos
Yarn
Sentinel
BurpSuite
MyBatis
查找
前端
Ubuntu
Spark RDD
FastDFS
Python
递归
Git
Golang基础
SQL练习题
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭