zoukankan      html  css  js  c++  java
  • Redis键是如何过期删除的

    前言

    在使用Redis作为缓存时候,我们期望Redis在我们指定的过期时间达到后能自动帮我们将该键进行DEL命令。
    但是有时候在系统运行过程中发现我们Redis的DB上存储了很多Key时候,我们明显对指定的Key进行了过期时间的设定,且过期时间条件已经成立了但是该Key依然存储在DB上。why?

    设置过期时间

    Redis有下面4个命令用于设置键的过期时间:

    • EXPIRE
      指定多少秒数后过期,具体用法参考
    • https://www.runoob.com/redis/keys-expire.html
    • PEXPIRE
      指定多少毫秒后过期,具体用法参考
    • https://www.runoob.com/redis/keys-pexpire.html
    • EXPIREAT
      指定timestamp时间戳的秒数为过期,具体用法参考
    • https://www.runoob.com/redis/keys-expireat.html
    • PEXPIREAT
      指定timestamp时间戳的毫秒数为过期,具体用法参考
    • https://www.runoob.com/redis/keys-pexpireat.html

    移除Key的过期时间

    使用命令PERSIST可移除指定Key的过期时间

    PERSIST test
    

      

    过期时间存储

    我们来了解下我们对Key写入的过期时间最终去向何方了?Redis有16个DB,每个DB对都是采取key-value格式存储键值对。
    Redis底层通过redisDB结构的dict字典存储了数据库的键值对,所以我们执行下面命令时候,是向DB1的dict字典写入了一个key为test value为"Hello"的键值对。

    localhost:1>SET test "Hello"
    

      

    当我们对指定key执行过期时间命令时,Redis也会将key对应的过期时间进行存储。redisDB结构内的expires字典存储了数据库中所有键的过期时间。我们对上面的test设置20秒的过期时间,执行如下命令:

    localhost:1>EXPIRE test 20
    

      

    检查过期时间

    可以直接通过TTL命令对Key的过期时间进行查询,如果返回值大于等于0表示Key暂未过期。

    localhost:1>TTL test
    

      

    过期删除策略

    到了关键地方了,就是我们的Key过期时间已到达后Redis是如何删除它的呢?这个也是面试时候面试官的高频提问之一了。
    Redis目前有3种删除策略

    • 定时删除
    • 惰性删除
    • 定期删除

    定时删除是在设置过期时间时候定义一个定时器,定时器会在Key的过期时间抵达时候执行对Key的删除命令;

    惰性删除与定时删除不同,惰性删除是在Redis每次从键空间获取键时候都检查本次取的键是否抵达过期时间,如果抵达过期时间则删除,没有则返回命令结果;

    定期删除是类似于定义了一个定时任务,每隔指定时间就对数据库的expires字典进行一次排查,对已过期的键执行删除命令,至于是否是全盘排查则取决于Redis的算法了;

    定时删除

    优点:
            保证Key抵达过期时间会执行删除命令从而释放过期键占用的内存资源;
    缺点:
            创建了大量的定时器,且同一过期时间下如需要删除多个键则会占用CPU资源,影响服务器的执行效率;

    惰性删除

    优点:
           服务器资源最大化利用,删除键的行为属于被动行为,每次都是在Redis对键进行取出时候执行,且不会影响到其他键。
    相比于定时删除策略,惰性删除策略对服务器资源的开销小了很多;
    缺点:
          不及时啊!!试想,我本来定义的Key的过期时间就是10秒后,如果我在20秒后才对Key进行取出操作则意味着Key真正的删除事件是20秒后。且如果有很多key都抵达了过期时间但是因为没有对他们进行取出操作则这些key永远无法删除,除非我们手动删除,大量的无用的key存储在DB上占用了内存空间,且很多时候运维人员是无感知的,除非自己主动检查....产生的后果可想而知~

    定期删除

    优点:
           不需要像定时删除一样每个key都新建一个定时器,也不用像惰性删除一样在没有执行读取操作时候积压过多无用的key。
    缺点:
          执行频率不好设定,执行时间太长则会积压过多已过期的key,执行评率太短又会消耗过多服务器资源~做人好难啊,做Redis的键值对过期删除策略更难~

    定期删除不是将Redis内所有DB的expires字典进行排查,而是分多次遍历数据库,如当前是遍历了DB0到DB5,下次则从DB6开始遍历。

    Redis默认的过期删除策略是采取惰性删除+定期删除两种策略,通过配合使用两种策略让服务器合理的分配资源。

  • 相关阅读:
    常用的PHP图形处理函数
    PHP常用文件操作函数
    PHP常用正则表达式函数浅析
    PHP类常量的常见访问方法
    使用PDO操作MySQL
    js数组的遍历方法,维持索引?splice与forEach && 孤儿对象形成,造成内存泄漏,置空等待垃圾回收
    [DOM] Input elements should have autocomplete attributes (suggested: "new-password"): (More info: https://goo.gl/9p2vKq)
    $(...).get(...).addClass is not a function
    使用淘宝镜像的命令
    对象、数组与JSON字符串之间的转换
  • 原文地址:https://www.cnblogs.com/hunanzp/p/12445318.html
Copyright © 2011-2022 走看看