Redis中的键值过期操作

1.过期设置

Redis 中设置过期时间主要通过以下四种方式:

  • expire key seconds:设置 key 在 n 秒后过期;
  • pexpire key milliseconds:设置 key 在 n 毫秒后过期;
  • expireat key timestamp:设置 key 在某个时间戳(精确到秒)之后过期;
  • pexpireat key millisecondsTimestamp:设置 key 在某个时间戳(精确到毫秒)之后过期;

下面分别来看以上这些命令的具体实现。

1)expire:N 秒后过期

127.0.0.1:6379> set key value
OK
127.0.0.1:6379> expire key 100
(integer) 1
127.0.0.1:6379> ttl key
(integer) 97

其中命令 ttl 的全称是 Time To Live 表示此键值在 n 秒后过期。例如,上面的结果 97 表示 key 在 97s 后过期。

2)pexpire:N 毫秒后过期

127.0.0.1:6379> set key2 value2
OK
127.0.0.1:6379> pexpire key2 100000
(integer) 1
127.0.0.1:6379> pttl key2
(integer) 94524

其中 pexpire key2 100000 表示设置 key2 在 100000 毫秒(100秒)后过期。

3)expireat:过期时间戳精确到秒

127.0.0.1:6379> set key3 value3
OK
127.0.0.1:6379> expireat key3 1573472683
(integer) 1
127.0.0.1:6379> ttl key3
(integer) 67

其中 expireat key3 1573472683 表示 key3 在时间戳 1573472683 后过期(精确到秒),使用 ttl 查询可以发现在 67s 后 key3 会过期。

小贴士:在 Redis 可以使用 time 命令查询当前时间的时间戳(精确到秒),示例如下:
127.0.0.1:6379> time

  1. “1573472563”
  2. “248426”

4)pexpireat:过期时间戳精确到毫秒

127.0.0.1:6379> set key4 value4
OK
127.0.0.1:6379> pexpireat key4 1573472683000
(integer) 1
127.0.0.1:6379> pttl key4
(integer) 3522

其中 pexpireat key4 1573472683000 表示 key4 在时间戳 1573472683000 后过期(精确到毫秒),使用 ttl 查询可以发现在 3522ms 后 key4 会过期。

5)字符串中的过期操作

字符串中几个直接操作过期时间的方法,如下列表:

  • set key value ex seconds:设置键值对的同时指定过期时间(精确到秒);
  • set key value ex milliseconds:设置键值对的同时指定过期时间(精确到毫秒);
  • setex key seconds valule:设置键值对的同时指定过期时间(精确到秒)。

实现示例如下:

① set key value ex seconds

127.0.0.1:6379> set k v ex 100
OK
127.0.0.1:6379> ttl k
(integer) 97

② set key value ex milliseconds

127.0.0.1:6379> set k2 v2 px 100000
OK
127.0.0.1:6379> pttl k2
(integer) 92483

③ setex key seconds valule

127.0.0.1:6379> setex k3 100 v3
OK
127.0.0.1:6379> ttl k3
(integer) 91

2.移除过期时间

使用命令: persist key 可以移除键值的过期时间,如下代码所示:

127.0.0.1:6379> ttl k3
(integer) 97
127.0.0.1:6379> persist k3
(integer) 1
127.0.0.1:6379> ttl k3
(integer) -1

可以看出第一次使用 ttl 查询 k3 会在 97s 后过期,当使用了 persist 命令之后,在查询 k3 的存活时间发现结果是 -1,它表示 k3 永不过期。

3.Java实现过期操作

本文将使用 Jedis 框架来实现对 Redis 过期时间的操作,如下代码所示:

public class TTLTest {public static void main(String[] args) throws InterruptedException {// 创建 Redis 连接Jedis jedis = new Jedis("xxx.xxx.xxx.xxx", 6379);// 设置 Redis 密码(如果没有密码,此行可省略)jedis.auth("xxx");// 存储键值对(默认情况下永不过期)jedis.set("k", "v");// 查询 TTL(过期时间)Long ttl = 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 文件中添加以下引用:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>version</version>
</dependency>

更多过期操作方法,如下列表:

  • pexpire(String key, long milliseconds):设置 n 毫秒后过期;
  • expireAt(String key, long unixTime):设置某个时间戳后过期(精确到秒);
  • pexpireAt(String key, long millisecondsTimestamp):设置某个时间戳后过期(精确到毫秒);
  • persist(String key):移除过期时间。

完整示例代码如下:

public class TTLTest {public static void main(String[] args) throws InterruptedException {// 创建 Redis 连接Jedis jedis = new Jedis("xxx.xxx.xxx.xxx", 6379);// 设置 Redis 密码(如果没有密码,此行可省略)jedis.auth("xxx");// 存储键值对(默认情况下永不过期)jedis.set("k", "v");// 查询 TTL(过期时间)Long ttl = 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(Redis Database)和 AOF(Append Only File),下面我们分别来看过期键在这两种格式中的呈现状态。

1)RDB中的过期键

RDB 文件分为两个阶段,RDB 文件生成阶段和加载阶段。

① RDB 文件生成

从内存状态持久化成 RDB(文件)的时候,会对 key 进行过期检查,过期的键不会被保存到新的 RDB 文件中,因此 Redis 中的过期键不会对生成新 RDB 文件产生任何影响。

② RDB 文件加载

RDB 加载分为以下两种情况:

  • 如果 Redis 是主服务器运行模式的话,在载入 RDB 文件时,程序会对文件中保存的键进行检查,过期键不会被载入到数据库中。所以过期键不会对载入 RDB 文件的主服务器造成影响;
  • 如果 Redis 是从服务器运行模式的话,在载入 RDB 文件时,不论键是否过期都会被载入到数据库中。但由于主从服务器在进行数据同步时,从服务器的数据会被清空。所以一般来说,过期键对载入 RDB 文件的从服务器也不会造成影响。

RDB 文件加载的源码可以在 rdb.c 文件的 rdbLoad() 函数中找到,源码所示:

/* Check if the key already expired. This function is used when loading
* an RDB file from disk, either at startup, or when an RDB was
* received from the master. In the latter case, the master is
* responsible for key expiry. If we would expire keys here, the
* snapshot taken by the master may not be reflected on the slave. 
*
* 如果服务器为主节点的话,
* 那么在键已经过期的时候,不再将它们关联到数据库中去
*/
if (server.masterhost == NULL && expiretime != -1 && expiretime < now) {decrRefCount(key);decrRefCount(val);// 跳过continue;
}

2)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 命令给所有的从库。

本文的知识点,如下图所示:
image.png

7.引用&鸣谢

https://segmentfault.com/a/1190000017776475

https://www.cnblogs.com/lukexwang/p/4710333.html

关注下面二维码,订阅更多精彩内容。

Java中文社群公众号二维码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

天意PE维护系统 V2021.7.16版

天意PE U盘维护系统是一款用于系统维护和装机的U盘PE系统&#xff08;U盘启动盘&#xff09;&#xff0c;采用双PE模式,支持UEFI双启动&#xff0c;集成常用工具的维护软件&#xff0c;集成SRS驱动&#xff0c;新版更加上了NVME硬盘的支持&#xff0c;天意U盘维护系统纯净、稳定…

Redis持久化的几种方式——深入解析RDB

Redis 的读写都是在内存中&#xff0c;所以它的性能较高&#xff0c;但在内存中的数据会随着服务器的重启而丢失&#xff0c;为了保证数据不丢失&#xff0c;我们需要将内存中的数据存储到磁盘&#xff0c;以便 Redis 重启时能够从磁盘中恢复原有的数据&#xff0c;而整个过程就…

【LeetCode】148. Sort List

Sort List Sort a linked list in O(n log n) time using constant space complexity. 要求时间复杂度为O(nlogn)&#xff0c;那么不能用quickSort了&#xff08;最坏O(n^2)&#xff09;&#xff0c;所以使用mergeSort. 通常写排序算法都是基于数组的&#xff0c;这题要求基于链…

WordPress网站搬家教程(根目录程序+ MySQL数据库)

WordPress博客网站怎么搬家到新的服务器上&#xff1f;WordPress搬家无非是两点&#xff0c;即WP程序文件和数据库&#xff0c;具体什么系统不用考虑&#xff1a; 3分钟详解WordPress搬家教程 本文新手站长网关于WordPress搬家教程是帮大家缕清思路&#xff08;参考&#xff1…

Redis持久化的几种方式——RDB深入解析

点击上方“Java中文社群”&#xff0c;选择“设为星标”终身学习者&#xff0c;以编程为乐&#xff01;Redis 的读写都是在内存中&#xff0c;所以它的性能较高&#xff0c;但在内存中的数据会随着服务器的重启而丢失&#xff0c;为了保证数据不丢失&#xff0c;我们需要将内存…

配置Debian11服务器允许root用户远程SSH登录

全新安装系统后&#xff0c;默认情况下将禁用Debian Linux上的root登录。当您尝试以root用户身份登录Debian11 Linux服务器时&#xff0c;访问将被拒绝。要在Debian Linux系统上为root用户启用SSH登录&#xff0c;您需要首先配置SSH服务器。 0.首先安装SSH 注意&#xff1a;如…

带你深入浅出的分析 HashTable 源码

Hashtable 一个元老级的集合类&#xff0c;早在 JDK 1.0 就诞生了&#xff0c;今天小编想和大家一起来揭开它的面纱&#xff01;01、摘要在集合系列的第一章&#xff0c;咱们了解到&#xff0c;Map 的实现类有 HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、…

Debian11服务器系统默认不存在sudo命令的解决办法

1.切换到root用户&#xff0c;安装vim&#xff0c;修改镜像源文件 apt-get install vim vim /etc/apt/sources.list注释掉原有的内容&#xff0c;添加如下阿里云的镜像源 deb http://mirrors.aliyun.com/debian/ bullseye main contrib deb-src http://mirrors.aliyun.com/…

Redis使用不当导致应用卡死

作者&#xff1a;小木来源&#xff1a;http://rrd.me/ezfTj首先说下问题现象&#xff1a;内网sandbox环境API持续1周出现应用卡死&#xff0c;所有api无响应现象刚开始当测试抱怨环境响应慢的时候 &#xff0c;我们重启一下应用&#xff0c;应用恢复正常&#xff0c;于是没做处…

阿里巴巴Linux开源镜像站 华为Linux开源镜像站 Linux宝塔面板

学习Linux系统和用Linux系统作服务器时&#xff0c;推荐Linux从Linux系统开源镜像站下载&#xff0c;国内源下载速度快&#xff0c;Linux系统可选择方案多&#xff01; 1.阿里巴巴开源镜像站&#xff1a; https://developer.aliyun.com/mirror/ 2.华为开源镜像站&#xff1a; …

阿里Java开发手册——如何优化数据库?

作者&#xff1a;杨冠宝/高海慧来自&#xff1a;码出高效 Java 开发手册数据库作为服务器端最为最为昂贵的资源之一&#xff0c;如果使用不当常常会导致系统卡顿或系统崩溃&#xff0c;那如何来优化数据库呢&#xff1f;下面来看阿里巴巴《Java开发手册》给出的优化方案。1 建立…

虚拟机VMware Workstation安装Linux服务器Debian11系统详细教程

虚拟机VMware Workstation安装Linux服务器Debian11系统详细教程如下&#xff1a; 准备好&#xff1a; 1.安装好虚拟机VMware Workstation 2.从Linux开源镜像下载的debian11镜像系统 从创建新的虚拟机开始 安装完系统重启进入系统&#xff0c;首先要做的是更新为阿里云的…

借力 Docker ,三分钟搞定 MySQL 主从复制!

hello 各位小伙伴大家好&#xff0c;今年 5 月份的时候&#xff0c;松哥和大家聊过如何搭建 MySQL 主从复制&#xff1a;提高性能&#xff0c;MySQL 读写分离环境搭建(一)提高性能&#xff0c;MySQL 读写分离环境搭建(二)不过很多小伙伴反映在 Linux 中安装 MySQL 比较费劲&…

阿里云服务器Debian11系统安装Linux宝塔面板 搭建WordPress个人博客

阿里云服务器可以使用Debian11镜像系统&#xff0c;在安装Linux宝塔面板&#xff0c;配置LNMP(LinuxNginxMySQLPHP&#xff09;后&#xff0c;再搭建WordPress个人博客。 一、安装Linux宝塔面板&#xff1a; https://www.bt.cn/ 复制debian安装linux宝塔面板命令&#xff0c…

面试官:聊一下你对MySQL索引的理解?

作者&#xff1a;浪人来源&#xff1a;http://t.cn/AiKmcEefMySQL索引&#xff1f;这玩意儿还能简单聊&#xff1f;明显是在挖坑&#xff0c;幸好老夫早有准备&#xff0c;切听我一一道来。 一、索引是什么?索引是帮助MySQL高效获取数据的数据结构。二、索引能干什么?索引非常…

Linux新建用户可以在shell中切换到该用户也能登录到图形桌面

解决使用useradd testname&#xff0c;passwd testname命令确实创建了一个用户&#xff0c;可以在shell中切换到该用户。但不能登录到图形桌面的问题&#xff01; 通过下面方法可以在Linux中新建用户&#xff0c;并创建用户主目录&#xff0c;也能登录到图形桌面 1.普通用户先…

这样写Java,同事直呼666

作者&#xff1a;涛姐涛哥来源&#xff1a;cnblogs.com/taojietaoge/p/11575376.html一、MyBatis 不要写 11当遇到多个查询条件&#xff0c;使用where 11 可以很方便的解决我们的问题&#xff0c;但是这样很可能会造成非常大的性能损失&#xff0c;因为添加了 “where 11 ”的过…

Lync Server 2010 安装部署系列三:添加DNS记录

为了让客户端能够自动登录系统&#xff0c;我们需要在DNS服务器上设置创建相关的SRV记录&#xff0c;首先在DNS服务器上创建一条A记录pool.Contoso.com对应IP地址为192.168.1.11&#xff0c;然后创建一条SRV记录对应刚才创建的A记录&#xff0c;服务的内容为_sipinternaltls&am…

Linux系统下MySQL导出数据库和导入数据库的命令

一、MySQL导出数据库用mysqldump命令 注意mysql的安装路径&#xff0c;即此命令的路径&#xff0c;如果你只要查询mysql的运行文件所在地址&#xff0c;直接用下面的命令就可以了&#xff0c;再切换到mysql的运行文件的路径 which mysqlcd /usr/bin/1、导出数据和表结构 命令格…

工作中 99% 会用到的 Git 命令

作者&#xff1a;命中水来源&#xff1a;https://www.cxiansheng.cn/daily/4901.分支操作git branch 创建分支git branch -b 创建并切换到新建的分支上git checkout 切换分支git branch 查看分支列表git branch -v 查看所有分支的最后一次操作git branch -vv 查看当前分支git b…