Redis 中设置过时时间主要经过如下四种方式:html
下面分别来看以上这些命令的具体实现。java
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 后过时。redis
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秒)后过时。shell
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> timesegmentfault
- "1573472563"
- "248426"
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
会过时。服务器
字符串中几个直接操做过时时间的方法,以下列表:框架
实现示例以下:函数
127.0.0.1:6379> set k v ex 100
OK
127.0.0.1:6379> ttl k
(integer) 97
复制代码
127.0.0.1:6379> set k2 v2 px 100000
OK
127.0.0.1:6379> pttl k2
(integer) 92483
复制代码
127.0.0.1:6379> setex k3 100 v3
OK
127.0.0.1:6379> ttl k3
(integer) 91
复制代码
使用命令: persist key
能够移除键值的过时时间,以下代码所示:spa
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
永不过时。
本文将使用 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>
复制代码
更多过时操做方法,以下列表:
完整示例代码以下:
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");
}
}
复制代码
上面咱们讲了过时键在 Redis 正常运行中一些使用案例,接下来,咱们来看 Redis 在持久化的过程当中是如何处理过时键的。 Redis 持久化文件有两种格式:RDB(Redis Database)和 AOF(Append Only File),下面咱们分别来看过时键在这两种格式中的呈现状态。
RDB 文件分为两个阶段,RDB 文件生成阶段和加载阶段。
从内存状态持久化成 RDB(文件)的时候,会对 key 进行过时检查,过时的键不会被保存到新的 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;
}
复制代码
当 Redis 以 AOF 模式持久化时,若是数据库某个过时键还没被删除,那么 AOF 文件会保留此过时键,当此过时键被删除后,Redis 会向 AOF 文件追加一条 DEL 命令来显式地删除该键值。
执行 AOF 重写时,会对 Redis 中的键值对进行检查已过时的键不会被保存到重写后的 AOF 文件中,所以不会对 AOF 重写形成任何影响。
当 Redis 运行在主从模式下时,从库不会进行过时扫描,从库对过时的处理是被动的。也就是即时从库中的 key 过时了,若是有客户端访问从库时,依然能够获得 key 对应的值,像未过时的键值对同样返回。
从库的过时键处理依靠主服务器控制,主库在 key 到期时,会在 AOF 文件里增长一条 del 指令,同步到全部的从库,从库经过执行这条 del 指令来删除过时的 key。
本文咱们知道了 Redis 中的四种设置过时时间的方式:expire、pexpire、expireat、pexpireat,其中比较经常使用的是 expire 设置键值 n 秒后过时。
字符串中能够在添加键值的同时设置过时时间,并可使用 persist 命令移除过时时间。同时咱们也知道了过时键在 RDB 写入和 AOF 重写时都不会被记录。
过时键在主从模式下,从库对过时键的处理要彻底依靠主库,主库删除过时键以后会发送 del 命令给全部的从库。
本文的知识点,以下图所示:
关注下面二维码,订阅更多精彩内容。