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

"1573472563"

"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 文件中添加以下引用:

redis.clients

jedis

version

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

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.引用&鸣谢

java redis 过期_Redis中的键值过期操作相关推荐

  1. Java删除properties配置文件中指定键值的代码

    将开发过程较好的一些内容片段记录起来,下面的内容段是关于Java删除properties配置文件中指定键值的内容. public static boolean deleteKeyValue4Pro(S ...

  2. Redis中的键值过期操作

    1.过期设置 Redis 中设置过期时间主要通过以下四种方式: expire key seconds:设置 key 在 n 秒后过期: pexpire key milliseconds:设置 key ...

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

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

  4. java 循环删除hashmap中的键值对,解决java.util.ConcurrentModificationException报错

    示例 import java.util.HashMap; import java.util.Iterator; import java.util.Map;public class DeleteHash ...

  5. python中字典的键是唯一的吗_python 零散记录(四) 强调字典中的键值唯一性 字典的一些常用方法...

    dict中键只有在值和类型完全相同的时候才视为一个键: mydict = {1:1,'':1} #此时mydict[1] 与 mydict['1']是两个不同的键值 dict的一些常用方法: clea ...

  6. Redis命令介绍之键值对操作

    前文已经提及过Redis中对于键值对操作的一些命令,如DEL.EXPIRE / PEXPIRE.TTL / PTTL以及EXISTS.今天我们继续介绍Redis中对键值对操作的相关命令. TYPE T ...

  7. 如何在 bash 中使用键值字典

    在字典中,字典存储一组键,每个键都有一个与之关联的值.可以使用对应的键在字典中插入.检索或更新值.字典数据结构针对基于键值的快速检索进行了优化,因此通常使用哈希表来实现.在不同的编程语言中,字典通常有 ...

  8. @PropertySource读取外部配置文件中的k-v保存到运行的环境变量中,加载完微博的配置文件以后使用${}取配置文件中的键值

    @PropertySource读取外部配置文件中的k-v保存到运行的环境变量中,加载完微博的配置文件以后使用${}取配置文件中的键值 该注解value={},可以使用String数组形式,读取多个配置 ...

  9. php使用redis生成自增序列号码,Redis使用Eval多个键值自增的操作实例

    在PHP上使用Redis 给多个键值进行自增,示例如下: $set['money'] = $this->redis->hIncrByFloat($key, $hour .'_money', ...

最新文章

  1. IOS中Cell自定义
  2. DirectX11 driver类型浅析
  3. 深度学习笔记三:Softmax Regression
  4. sql-labs page2(21~38) 解题过程记录
  5. 欧拉回路基本概念+判断+求解
  6. 微信小程序条码、二维码生成模块
  7. 硬件电路基础知识(30)---RS232、RS485、RS422、RJ45接口的区别
  8. Android View 如何测量
  9. 制作 Pidgin QQ 表情包
  10. 单片机74LS164C语言例子,51单片机控制74LS164芯片输出64位的数组
  11. 图像检测与分割标注文件XML/JSON/TXT一键批量转换编辑软件
  12. Linux系统管理命令之accton的使用
  13. 东莞市中考计算机考试试题,东莞中考信息技术特长生考试程序内容及评分标准...
  14. 【避坑指南】Win7虚拟机中VMwareTools 安装报错问题解决
  15. Altium中PCB板上开窗
  16. android10 禁止下拉状态栏
  17. 什么是集合,集合的定义,集合与数组的区别,怎么创建一个集合?
  18. 赋范线性空间上的有界线性泛函
  19. Failed to shutdown DBConsole Gracefully
  20. Java11新特性概览

热门文章

  1. 晶振、时钟周期、机器周期
  2. MySQL 运维 日志 -- 错误日志、二进制日志、查询日志、慢查询日志
  3. css预处理器-stylus 很少人用
  4. 2022-2027年中国煤制尿素行业市场全景评估及发展战略规划报告
  5. 用 pandas 实现真实的Vlookup
  6. 关于Manifest
  7. ChinaSoft 论坛巡礼 | CCF-华为胡杨林基金-形式化方法专项论坛
  8. javaScript canvas从入门到骨灰级玩家(基础篇)
  9. 第一天:Hbase 概述
  10. hyper扩展linux硬盘,Hyper-V 虚拟机扩展磁盘