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

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

7.引用&鸣谢

https://segmentfault.com/a/1190000017776475

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

Redis中的键值过期操作的更多相关文章

  1. Spark中的键值对操作-scala

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  2. Spark中的键值对操作

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  3. kombu在redis中的键值名

    参考flower源码 取队列名,发送到求数量的函数中 queue_names = ControlHandler.get_active_queue_names() queues = yield brok ...

  4. redis 中的key值过期后,触发通知事件

    1.创建springboot工程,创建监听类 maven配置 <dependencies> <dependency> <groupId>org.springfram ...

  5. Redis源码解析:09redis数据库实现(键值对操作、键超时功能、键空间通知)

    本章对Redis服务器的数据库实现进行介绍,说明Redis数据库相关操作的实现,包括数据库中键值对的添加.删除.查看.更新等操作的实现:客户端切换数据库的实现:键超时相关功能的实现.键空间事件通知等. ...

  6. C语言定义从URL中获取键值的接口

    环境:centos7下,对客户端http请求进行解析,来获取有效键值(包括汉字). 头文件 /* 这是一份关于从Http请求信息中提取键值的接口声明的头文件 */ #ifndef _HEAD_H_ # ...

  7. 在C#中用Linq从属性文件中读取键值对Key-Value Pair

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在C#中用Linq从属性文件中读取键值对Key-Value Pair.

  8. js中以键值对的形式当枚举

    js中以键值对的形式当枚举var Penum= { B: "姓名", C: "所属居委", D: "证件号", E: "性别&qu ...

  9. PHP如何根据数组中的键值进行排序

    主要是使用PHP的排序函数,asort()和arsort(). 为了减少代码的耦合性,我们将根据数组中的键值进行排序封装成一个函数 <?php $array = array( array(), ...

随机推荐

  1. Rust入坑指南:坑主驾到

    欢迎大家和我一起入坑Rust,以后我就是坑主,我主要负责在前面挖坑,各位可以在上面看,有手痒的也可以和我一起挖.这个坑到底有多深?我也不知道,我是抱着有多深就挖多深的心态来的,下面我先跳了,各位请随意 ...

  2. centos 7安装rac 11gR2时运行root.sh报错找不到ohas服务(ohasd failed to start)

    单独在linux 7中为ohasd设置一个服务.步骤如下1. 创建服务ohas.service的服务文件并赋予权限touch /usr/lib/systemd/system/ohas.servicec ...

  3. ubuntu下安装及配置git的方法

    安装Git 一个全新的ubunt系统,需要安装Git(系统是不具有该工具的),方法如下: 在terminel中输入如下命令: sudo apt-get install git git-core git ...

  4. Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝

    Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝ 教程 Xadmin安装方法: settings.py 的配置

  5. python requests简单接口自动化

    get方法 url:显而易见,就是接口的地址url啦 headers:定制请求头(headers),例如:content-type = application/x-www-form-urlencode ...

  6. HDU 6112 今夕何夕 (预处理 枚举)

    中文题意都看的懂啦~ 思路很简单,就是通过前一天推出当天是星期几,直接枚举所有2017-9999年的每一天就好了.ㄟ( ▔, ▔ )ㄏ 代码: #include <cstdio> #def ...

  7. 关于a标签的href属性

    今天有人问起我a标签的href属性值为 # 与 JavaScript:void(0) 有啥区别,想来也没啥可说,就简单说两句 a标签的href属性,优点有: 天然鼠标手型,以及可以被键盘focus以及 ...

  8. Class constructor FileManager cannot be invoked without 'new'

    bug:今天项目重新安装依赖打包的时候出现错误:Class constructor FileManager cannot be invoked without 'new' 解决:尝试了很多种解决方案, ...

  9. 使用face-api.js实现人脸识别(一)

    功能 第一阶段实现对图片中人脸的识别并打上标签(比如:人名) 第二阶段使用摄像头实现对人物的识别,比如典型的应用做一个人脸考勤的系统 资源 face-api.js https://github.com ...

  10. Linux进程和线程

    一.进程产生的方式 1.描述进程的ID号通常叫做PID,即进程ID,PID的变量类型为pid_t. 2.getpid(void)返回当前进程的ID号,getppid(void)返回当前进程的父进程的I ...