Redis有四个不同的命令可以用于设置键的生存时间或过期时间
命令 | 参数 | 描述 |
---|---|---|
EXPIRE | <key> <ttl> | 将键key的生存时间设置为ttl秒 |
PEXPIRE | <key> <ttl> | 将键key的生存时间设置为ttl毫秒 |
EXPIREAT | <key> <timestamp> | 将键key的生存时间设置为timestamp所制定的秒数时间戳 |
PEXPIREAT | <key> <timestamp> | 将键key的生存时间设置为timestamp所制定的毫秒数时间戳 |
PERSIST | <key> | 将键key的过期时间移除 |
TTL | <key> | 以秒为单位返回剩余时间 |
PTTL | <key> | 以毫秒为单位返回剩余时间 |
过期键的判定
expires字典保存了所有键的过期时间(过期字典)。过期字典的键是一个指针,指向键空间某个对象。过期字典的值是一个long long类型的整数,保存了键所指向的对象的过期时间(毫秒精度的UNIX时间戳)。
1、检查给定的键是否存在于过期字典:如果存在,那么取得键的过期时间。
2、检查当前UNIX时间戳是否大于键的过期时间:如果是的话,那么键已经过期;否则的话,键未过期。
过期删除策略
定时删除
在设置见得过期时间的同事,创建一个定时器,让定时器在键过期时间来临时,立即执行对键的删除操作。
保证尽可能快的删除指定键,并释放过期键所占用的内存。
对CPU时间不友好,当过期键较多时会占用CPU资源。创建定时器依赖时间事件(无序链表),查找一个时间的时间复杂度为O(n),并不能高效地处理大量时间事件。
惰性删除
放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没过期就返回该键。
CPU友好,程序只会在取出键的时候才会对键进行过期检查。切不会关心其他无关的过期键。
只要不被访问,过期的键会一直保存在内存中。
定期删除
每隔一段时间,程序就会对数据库进行检查一次,删除里面的过期键。
如果定期删除执行的太频繁,或者执行的时间太长,定期删除策略会退化成定时删除策略,以至于将CPU资源你过多的小号在删除过期键上
如果定期删除执行的太少,或者时间太短,定期删除策略会和惰性删除策略一样,出现浪费内存的情况。
Redis的过期键删除策略
配合使用惰性删除和定期删除策略来合理使用CPU资源和避免浪费内存空间。
RDB对过期键的处理
生成RDB文件
执行SAVE和BGSAVE命令创建RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中。
载入RDB文件
如果服务器为主服务器,在载入RDB文件时,程序会对文件中保存的键进行检查,未过期的键会被载入到数据库中,而过期键则会被忽略。
如果服务器为从服务器,在载入RDB文件时,会保存所有的键。对于过期的键,在与主服务器同步时会被清空
AOF对过期键的处理
AOF文件写入
当过期键被删除后,AOF会追加一条DEL命令,来显示的记录该键已经被删除。
AOF重写
在执行AOF从写的过程中,程序会对数据库中的键进行检查,已经过期的键不会被保存到重写后的AOF文件中。
主从复制
主服务器在删除一个过期键后,会显示地向所有从服务器发送一个DEL命令。
从服务器在执行客户端发送的独命令时,即使碰到过期键也不会将过期键删除,而是像未过期的键一样处理、
从服务器只有接到主服务器发来的DEL命令之后,才会删除过期键。