龙空技术网

需要注意的Redis过期时间的一些知识

一个程序员的学习故事 71

前言:

如今看官们对“ttl卸载系统应用”大概比较注重,看官们都想要剖析一些“ttl卸载系统应用”的相关资讯。那么小编也在网上网罗了一些对于“ttl卸载系统应用””的相关知识,希望各位老铁们能喜欢,咱们一起来学习一下吧!

Redis的每个Key都可以设置一个过期时间,当达到过期时间的时候,这个key就会被自动删除。

那么应该在使用过程中注意哪些事项呢?

DEL/SET/GETSET等命令会清除过期时间

在使用会覆盖key对应value的命令操作一个设置了过期时间的key的时候,会导致对应的key的过期时间被清除,如DEL、SET、GETSET等。

//设置test的过期时间为300s127.0.0.1:6379> set test 1 ex 300OK//查看过期时间127.0.0.1:6379> ttl test(integer) 296//使用set命令覆盖mykey的内容127.0.0.1:6379> set test 2OK//过期时间被清除127.0.0.1:6379> ttl test(integer) -1
INCR/LPUSH/HSET等命令则不会清除过期时间

如果只是修改一个key的value,而不是覆盖整个value的命令,则不会清除key的过期时间。

//设置incr_key的过期时间为300s127.0.0.1:6379> set incr_key 1 ex 300OK127.0.0.1:6379> ttl incr_key(integer) 291//进行自增操作127.0.0.1:6379> incr incr_key(integer) 2127.0.0.1:6379> get incr_key"2"//查询过期时间,发现过期时间没有被清除127.0.0.1:6379> ttl incr_key(integer) 277
PERSIST命令会清除过期时间

当使用PERSIST命令将一个设置了过期时间的key转变成一个持久化的key的时候,也会清除过期时间。

127.0.0.1:6379> set persist_key haha ex 300OK127.0.0.1:6379> ttl persist_key(integer) 296//将key变为持久化的127.0.0.1:6379> persist persist_key(integer) 1//过期时间被清除127.0.0.1:6379> ttl persist_key(integer) -1
使用RENAME命令,老key的过期时间将会转到新key上

在使用例如:RENAME KEY_A KEY_B命令将KEY_A重命名为KEY_B,不管KEY_B有没有设置过期时间, KEY_B将会继承KEY_A的所有特性。

在使用例如:RENAME KEY_A KEY_B命令将KEY_A重命名为KEY_B,不管KEY_B有没有设置过期时间,新的key KEY_B将会继承KEY_A的所有特性。
使用EXPIRE/PEXPIRE设置的过期时间为负数或者使用EXPIREAT/PEXPIREAT设置过期时间戳为过去的时间会导致key被删除
127.0.0.1:6379> set key_1 value_1OK127.0.0.1:6379> get key_1"value_1"//设置过期时间为-1127.0.0.1:6379> expire key_1 -1(integer) 1//发现key被删除127.0.0.1:6379> get key_1(nil)
127.0.0.1:6379> set key_2 value_2OK127.0.0.1:6379> get key_2"value_2"//设置的时间戳为过去的时间127.0.0.1:6379> expireat key_2 10000(integer) 1//key被删除127.0.0.1:6379> get key_2(nil)
EXPIRE命令可以更新过期时间

对一个已经设置了过期时间的key使用expire命令,可以更新其过期时间。

//设置key_1的过期时间为100s127.0.0.1:6379> set key_1 value_1 ex 100OK127.0.0.1:6379> ttl key_1(integer) 95//更新key_1的过期时间为300s127.0.0.1:6379> expire key_1 300(integer) 1127.0.0.1:6379> ttl key_1(integer) 295

在Redis2.1.3以下的版本中,使用expire命令更新一个已经设置了过期时间的key的过期时间会失败。并且对一个设置了过期时间的key使用LPUSH/HSET等命令修改其value的时候,会导致Redis删除该key。

Redis的过期策略

Redis使用懒惰删除+定期删除相结合的方式处理过期的key。

懒惰删除

所谓懒惰删除就是在客户端访问该key的时候,redis会对key的过期时间进行检查,如果过期了就立即删除。

这种方式看似很完美,在访问的时候检查key的过期时间,不会占用太多的额外CPU资源。但是如果一个key已经过期了,如果长时间没有被访问,那么这个key就会一直存留在内存之中,严重消耗了内存资源。

定期删除

定期删除的原理是,Redis会将所有设置了过期时间的key放入一个字典中,然后每隔一段时间从字典中随机一些key检查过期时间并删除已过期的key。

Redis默认每秒进行10次过期扫描:

从过期字典中随机20个key删除这20个key中已过期的如果超过25%的key过期,则重复第一步

同时,为了保证不出现循环过度的情况,Redis还设置了扫描的时间上限,默认不会超过25ms。

内存不足,主动清理

在redis的内存不足时,也会触发主动清理。

redis是一个基于内存的数据库,如果存储的数据量很大,达到了内存限制的最大值,将会出现内存不足的问题。redis允许用户通过配置maxmemory-policy参数,指定redis在内存不足时的解决策略。

1.volatile-lru 使用LRU算法删除一个键(只针对设置了过期时间的key);

2.allkeys-lru 使用LRU算法删除一个键;

3.volatile-lfu 使用LFU算法删除一个键(只针对设置了过期时间的键);

4.allkeys-lfu 使用LFU算法删除一个键;

5.volatile-random 随机删除一个键(只针对设置了过期时间的键);

6.allkeys-random 随机删除一个键;

7.volatile-ttl 删除最早过期的一个键;

8.noeviction 不删除键,返回错误信息(redis默认选项)

对于只针对设置了过期时间的键进行删除的策略,在所有的可被删除的键(非永久的键)都被删除时内存依然不足,将会抛出错误。

其中,

LRU算法--->最近最少使用算法,较为注重于时间;

LFU算法--->最近最不常用算法,较为注重于被访问频率。

标签: #ttl卸载系统应用