Redis中键值过期操作示例详解
1.过期设置
Redis中设置过期时间主要通过以下四种方式:
- expirekeyseconds:设置key在n秒后过期;
- pexpirekeymilliseconds:设置key在n毫秒后过期;
- expireatkeytimestamp:设置key在某个时间戳(精确到秒)之后过期;
- pexpireatkeymillisecondsTimestamp:设置key在某个时间戳(精确到毫秒)之后过期;
下面分别来看以上这些命令的具体实现。
1)expire:N秒后过期
127.0.0.1:6379>setkeyvalue OK 127.0.0.1:6379>expirekey100 (integer)1 127.0.0.1:6379>ttlkey (integer)97
其中命令ttl的全称是TimeToLive表示此键值在n秒后过期。例如,上面的结果97表示key在97s后过期。
2)pexpire:N毫秒后过期
127.0.0.1:6379>setkey2value2 OK 127.0.0.1:6379>pexpirekey2100000 (integer)1 127.0.0.1:6379>pttlkey2 (integer)94524
其中pexpirekey2100000表示设置key2在100000毫秒(100秒)后过期。
3)expireat:过期时间戳精确到秒
127.0.0.1:6379>setkey3value3 OK 127.0.0.1:6379>expireatkey31573472683 (integer)1 127.0.0.1:6379>ttlkey3 (integer)67
其中expireatkey31573472683表示key3在时间戳1573472683后过期(精确到秒),使用ttl查询可以发现在67s后key3会过期。
小贴士:在Redis可以使用time命令查询当前时间的时间戳(精确到秒),示例如下:
127.0.0.1:6379>time
1)"1573472563"
2)"248426"
4)pexpireat:过期时间戳精确到毫秒
127.0.0.1:6379>setkey4value4 OK 127.0.0.1:6379>pexpireatkey41573472683000 (integer)1 127.0.0.1:6379>pttlkey4 (integer)3522
其中pexpireatkey41573472683000表示key4在时间戳1573472683000后过期(精确到毫秒),使用ttl查询可以发现在3522ms后key4会过期。
5)字符串中的过期操作
字符串中几个直接操作过期时间的方法,如下列表:
- setkeyvalueexseconds:设置键值对的同时指定过期时间(精确到秒);
- setkeyvalueexmilliseconds:设置键值对的同时指定过期时间(精确到毫秒);
- setexkeysecondsvalule:设置键值对的同时指定过期时间(精确到秒)。
实现示例如下:
①setkeyvalueexseconds
127.0.0.1:6379>setkvex100 OK 127.0.0.1:6379>ttlk (integer)97
②setkeyvalueexmilliseconds
127.0.0.1:6379>setk2v2px100000 OK 127.0.0.1:6379>pttlk2 (integer)92483
③setexkeysecondsvalule
127.0.0.1:6379>setexk3100v3 OK 127.0.0.1:6379>ttlk3 (integer)91
2.移除过期时间
使用命令:persistkey可以移除键值的过期时间,如下代码所示:
127.0.0.1:6379>ttlk3 (integer)97 127.0.0.1:6379>persistk3 (integer)1 127.0.0.1:6379>ttlk3 (integer)-1
可以看出第一次使用ttl查询k3会在97s后过期,当使用了persist命令之后,在查询k3的存活时间发现结果是-1,它表示k3永不过期。
3.Java实现过期操作
本文将使用Jedis框架来实现对Redis过期时间的操作,如下代码所示:
publicclassTTLTest{ publicstaticvoidmain(String[]args)throwsInterruptedException{ //创建Redis连接 Jedisjedis=newJedis("xxx.xxx.xxx.xxx",6379); //设置Redis密码(如果没有密码,此行可省略) jedis.auth("xxx"); //存储键值对(默认情况下永不过期) jedis.set("k","v"); //查询TTL(过期时间) Longttl=jedis.ttl("k"); //打印过期日志 System.out.println("过期时间:"+ttl); //设置100s后过期 jedis.expire("k",100); //等待1s后执行 Thread.sleep(1000); //打印过期日志 System.out.println("执行expire后的TTL="+jedis.ttl("k")); } }
程序的执行结果为:
过期时间:-1
执行expire后的TTL=99
可以看出使用Jedis来操作Redis的过期时间还是很方便的,可直接使用jedis.ttl("k")查询键值的生存时间,使用jedis.expire("k",seconds)方法设置过期时间(精确到秒)。
小贴士:使用Jedis之前,先要把Jedis引入到程序中,如果使用的是Maven项目的,直接在pom.xml文件中添加以下引用:
redis.clients jedis version
更多过期操作方法,如下列表:
- pexpire(Stringkey,longmilliseconds):设置n毫秒后过期;
- expireAt(Stringkey,longunixTime):设置某个时间戳后过期(精确到秒);
- pexpireAt(Stringkey,longmillisecondsTimestamp):设置某个时间戳后过期(精确到毫秒);
- persist(Stringkey):移除过期时间。
完整示例代码如下:
publicclassTTLTest{ publicstaticvoidmain(String[]args)throwsInterruptedException{ //创建Redis连接 Jedisjedis=newJedis("xxx.xxx.xxx.xxx",6379); //设置Redis密码(如果没有密码,此行可省略) jedis.auth("xxx"); //存储键值对(默认情况下永不过期) jedis.set("k","v"); //查询TTL(过期时间) Longttl=jedis.ttl("k"); //打印过期日志 System.out.println("过期时间:"+ttl); //设置100s后过期 jedis.expire("k",100); //等待1s后执行 Thread.sleep(1000); //打印过期日志 System.out.println("执行expire后的TTL="+jedis.ttl("k")); //设置n毫秒后过期 jedis.pexpire("k",100000); //设置某个时间戳后过期(精确到秒) jedis.expireAt("k",1573468990); //设置某个时间戳后过期(精确到毫秒) jedis.pexpireAt("k",1573468990000L); //移除过期时间 jedis.persist("k"); } }
4.持久化中的过期键
上面我们讲了过期键在Redis正常运行中一些使用案例,接下来,我们来看Redis在持久化的过程中是如何处理过期键的。
Redis持久化文件有两种格式:RDB(RedisDatabase)和AOF(AppendOnlyFile),下面我们分别来看过期键在这两种格式中的呈现状态。
1)RDB中的过期键
RDB文件分为两个阶段,RDB文件生成阶段和加载阶段。
①RDB文件生成
从内存状态持久化成RDB(文件)的时候,会对key进行过期检查,过期的键不会被保存到新的RDB文件中,因此Redis中的过期键不会对生成新RDB文件产生任何影响。
②RDB文件加载
RDB加载分为以下两种情况:
- 如果Redis是主服务器运行模式的话,在载入RDB文件时,程序会对文件中保存的键进行检查,过期键不会被载入到数据库中。所以过期键不会对载入RDB文件的主服务器造成影响;
- 如果Redis是从服务器运行模式的话,在载入RDB文件时,不论键是否过期都会被载入到数据库中。但由于主从服务器在进行数据同步时,从服务器的数据会被清空。所以一般来说,过期键对载入RDB文件的从服务器也不会造成影响。
RDB文件加载的源码可以在rdb.c文件的rdbLoad()函数中找到,源码所示:
/*Checkifthekeyalreadyexpired.Thisfunctionisusedwhenloading *anRDBfilefromdisk,eitheratstartup,orwhenanRDBwas *receivedfromthemaster.Inthelattercase,themasteris *responsibleforkeyexpiry.Ifwewouldexpirekeyshere,the *snapshottakenbythemastermaynotbereflectedontheslave. * *如果服务器为主节点的话, *那么在键已经过期的时候,不再将它们关联到数据库中去 */ if(server.masterhost==NULL&&expiretime!=-1&&expiretime2)AOF中的过期键
①AOF文件写入
当Redis以AOF模式持久化时,如果数据库某个过期键还没被删除,那么AOF文件会保留此过期键,当此过期键被删除后,Redis会向AOF文件追加一条DEL命令来显式地删除该键值。
②AOF重写
执行AOF重写时,会对Redis中的键值对进行检查已过期的键不会被保存到重写后的AOF文件中,因此不会对AOF重写造成任何影响。
5.主从库的过期键
当Redis运行在主从模式下时,从库不会进行过期扫描,从库对过期的处理是被动的。也就是即时从库中的key过期了,如果有客户端访问从库时,依然可以得到key对应的值,像未过期的键值对一样返回。
从库的过期键处理依靠主服务器控制,主库在key到期时,会在AOF文件里增加一条del指令,同步到所有的从库,从库通过执行这条del指令来删除过期的key。
6.小结
本文我们知道了Redis中的四种设置过期时间的方式:expire、pexpire、expireat、pexpireat,其中比较常用的是expire设置键值n秒后过期。
字符串中可以在添加键值的同时设置过期时间,并可以使用persist命令移除过期时间。同时我们也知道了过期键在RDB写入和AOF重写时都不会被记录。
过期键在主从模式下,从库对过期键的处理要完全依靠主库,主库删除过期键之后会发送del命令给所有的从库。
本文的知识点,如下图所示:
7.引用&鸣谢
https://www.nhooo.com/article/174204.htm
https://www.nhooo.com/article/174207.htm
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。