zoukankan      html  css  js  c++  java
  • Redis-设置Key的过期时间及相关策略



    部分内容转载自:

    微信公众号:搜云库技术团队

    部分内容原文地址:Redis中设置了过期时间的Key,那么你还要知道些什么?



    1、设置key的过期时间

    1.1expire key second:设置key的过期时间(秒)

    127.0.0.1:6379> expire key1 100 key1在100秒后过期
    (integer) 1
    

    1.2ttl key:查看key的有效期

    127.0.0.1:6379> ttl key1
    (integer) 73 大于0,还剩余多少秒存活时间
    127.0.0.1:6379> ttl key1
    (integer) -2 -2 不存在redis中,
    127.0.0.1:6379> ttl list1
    (integer) -1 -1 永久有效,持久化
    

    1.3persist key:清除key的过期时间。Key持久化

    127.0.0.1:6379> set str2 bbb 新增str2值
    OK
    127.0.0.1:6379> ttl str2 查看str2目前的有效期:持久化
    (integer) -1
    127.0.0.1:6379> expire str2 100 设置str2的有效期100秒
    (integer) 1
    127.0.0.1:6379> ttl str2 查看str2目前的有效期:倒计时
    (integer) 96
    127.0.0.1:6379> persist str2 清除str2的过期时间
    (integer) 1
    127.0.0.1:6379> ttl str2 查看str2目前的有效期:持久化
    (integer) -1
    

    2、为key设置过期时间需要注意的事项

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

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

    //设置mykey的过期时间为300s
    127.0.0.1:6379> set mykey hello ex 300
    OK
    //查看过期时间
    127.0.0.1:6379> ttl mykey
    (integer) 294
    //使用set命令覆盖mykey的内容
    127.0.0.1:6379> set mykey olleh
    OK
    127.0.0.1:6379> ttl mykey
    (integer) -1
    

    2.2INCR/LPUSH/HSET等命令则不会清除过期时间

    而在使用INCR/LPUSH/HSET这种只是修改一个key的value,而不是覆盖整个value的命令,则不会清除key的过期时间。

    INCR:

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

    LPUSH:

    //新增一个list类型的key,并添加一个为1的值
    127.0.0.1:6379> LPUSH list 1
    (integer)1
    //为list设置300s的过期时间
    127.0.0.1:6379> expire list 300
    (integer)1
    //查看过期时间
    127.0.0.1:6379> ttl list
    (integer) 292
    //往list里面添加值2
    127.0.0.1:6379> lpush list 2
    (Integer) 2
    //查看list的所有值
    127.0.0.1:6379> lrange list 0 1
    1)"2"
    2)"1"
    //能看到往list里面添加值并没有使过期时间清除
    127.0.0.1:6379> ttl list
    (integer) 252
    

    2.3PERSIST命令会清除过期时间

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

    127.0.0.1:6379> set persist_key haha ex 300
    OK
    127.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
    

    2.4使用RENAME命令,老key的过期时间将会转到新key上

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

    //设置key_a的过期时间为300s
    127.0.0.1:6379> set key_a value_a ex 300
    OK
    //设置key_b的过期时间为600s
    127.0.0.1:6379> set key_b value_b ex 600
    OK
    127.0.0.1:6379> ttl key_a
    (integer) 279
    127.0.0.1:6379> ttl key_b
    (integer) 591
    //将key_a重命名为key_b
    127.0.0.1:6379> rename key_a key_b
    OK
    //新的key_b继承了key_a的过期时间
    127.0.0.1:6379> ttl key_b
    (integer) 248
    

    2.5使用EXPIRE/PEXPIRE设置的过期时间为负数或者使用EXPIREAT/PEXPIREAT设置过期时间戳为过去的时间会导致key被删除

    EXPIRE:

    127.0.0.1:6379> set key_1 value_1
    OK
    127.0.0.1:6379> get key_1
    "value_1"
    //设置过期时间为-1
    127.0.0.1:6379> expire key_1 -1
    (integer) 1
    //发现key被删除
    127.0.0.1:6379> get key_1
    (nil)
    

    EXPIREAT:

    127.0.0.1:6379>set key_2 value_2
    OK
    127.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)
    

    2.6EXPIRE命令可以更新过期时间

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

    //设置key_1的过期时间为100s
    127.0.0.1:6379> set key_1 value_1 ex 100
    OK
    127.0.0.1:6379> ttl key_1
    (integer)95
    //更新key_1的过期时间为300s
    127.0.0.1:6379> expire key_1 300
    (integer)1
    127.0.0.1:6379> ttl key_1
    (integer) 295
    

    3、Redis的过期策略

    Redis是单线程的,所以一些耗时的操作会导致Redis卡顿,比如当Redis数据量特别大的时候,使用keys * 命令列出所有的key。

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

    3.1懒惰删除

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

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

    3.2定期删除

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

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

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

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

  • 相关阅读:
    基本数据结构——栈
    错误 1 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. d:usersvs2013le
    Java内存区域
    VS2010 无法计算HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSBuildToolsVersions14.0@VCTargetPath处的属性表达式
    PHP高并发场景下的一点思路
    LINUX运维常用命令
    php7的一些新特性总结
    MySQL读写分离主从配置
    php 生成唯一id的几种解决方法
    浅谈mysql两种常用引擎MyIASM和InnoDB的区别
  • 原文地址:https://www.cnblogs.com/aixing/p/13327302.html
Copyright © 2011-2022 走看看