redis键过期删除策略

设置键过期时间的命令

  • EXPIRE
  • PEXPIRE
  • EXPIREAT
  • PEXPIREAT

保存键的过期时间

在redisDb中,用一个名为expire的字典保存了所有键的过期时间,称它为过期字典。

  • 过期字典的键是一个指针,指向了键空间的某个数据库键对象
  • 过期字典的值是一个long long类型,保存了数据库键的过期时间,即一个毫秒精度的unix时间戳
    /* Redis database representation. There are multiple databases identified
    * by integers from 0 (the default database) up to the max configured
    * database. The database number is the 'id' field in the structure. */
    typedef struct redisDb {
      dict *dict;                 /* The keyspace for this DB */
      dict *expires;              /* Timeout of keys with a timeout set */
      ......
    } redisDb;
    

过期键的判定

  • 检测过期字典里是否存在键,如果不存在则返回false,存在则取过期时间
  • 检测当前unix时间戳是否大于过期时间,大于表示键过期,否则未过期

过期键删除策略

定时删除

设置键过期时间的同时,设置一个定时器在过期时间来临时删除键

  • 优点是保证了过期键会尽可能快的删掉,释放占用的内存
  • 删除操作会占用cpu时间,在有大量键需要删除,而内存不紧张但cpu时间紧张的情况下,会对响应时间和吞吐量造成影响

惰性删除

放任过期键不管,每次获取键时都得检查是否过期,过期则删除,未过期则返回值

  • 优点是对cpu时间优化,保证只有在非做不可的时候才会删除,而不会在其它无关的过期键浪费时间
  • 缺点是对内存不友好,如果存在非常多的过期键会占用大量内存

定期删除

每隔一段时间,对数据库检查删除过期键,而删除多少,检查多少个数据库由算法决定。定期删除实际上是上面两种算法的折中。

  • 优点是可以限制删除操作执行的时长和频次,减少对cpu时间的影响;定期删除能有效减少内存浪费
  • 缺点是难以确定时长和频次,如果删除太频繁或者执行时间太长,会占用cpu资源;如果删除频次太少或者执行时间太短,又会造成内存浪费

redis的删除策略,惰性删除和定期删除的结合

惰性删除的实现

所有读写数据库的redis命令执行前,都会调用expireIfNeeded函数来做检查,如果输入键未过期则不做处理,如果过期则expireIfNeeded函数将它删除

定期删除的实现

周期性调用activeExpireCycle函数,分多次遍历服务器中的各个数据库,从数据库字典中随机检查一部分键的过期时间,并且删除其中的过期键

过期键对RDB,AOF,复制的影响

RDB

  • 生成RDB文件时,已过期的键不会保存
  • 载入RDB文件时,如果是主服务器不会载入过期键,如果是从服务器会载入,因为主从复制时从服务器也会清空

    AOF

  • AOF文件写入时,当过期键被删除时,会向AOF文件追加一条DEL命令显示删除该记录
  • AOF文件重写时,过期键不会重写到AOF文件中

    复制

    在复制模式下,从服务器的过期删除动作由主服务器控制
  • 主服务器删除过期键,会显示通知所有从服务器删除,通过发送DEL命令的方式
  • 从服务器执行读命令时碰到过期键不会惰性删除,而是会返回数据给客户端
  • 从服务器只有接收了DEL命令时,才会删除过期键

你可能感兴趣的:(redis键过期删除策略)