本节我们来讲一下Redis的过期机制
Redis经常用作缓存,很多都是临时缓存,比如验证码等session信息,我们希望它们能在一定时间内自动销毁。Redis提供了一些对key设置过期时间的命令。
一、过期字典
Redis对存储值的过期处理实际上是对键(key)设置过期时间,然后到期自动删除这个键。
我们要知道在redis数据库的结构设计中,是采用expires字典保存了数据库中所有键的过期时间,被称为过期字典
- 过期字典的键是一个指针,指向键空间中的某个键对象(设置过期时间的键对象)
- 过期字典的值是一个long long 类型的整数,保存了一个毫秒精度UNIX时间戳的过期时间
当一个数据库键设置过期时间时,服务器会在过期字典中关联指定的数据库键和过期时间
二、设置键的过期时间
设置数据库键的过期时间有以下几种命令:
- EXPIRE key time 设置生存时间为time秒
-
PEXPIRE key time 设置生存时间为time 毫秒
-
EXPIREAT key timestamp 设置过期时间为timestamp指定的时间戳
-
PEXPIREAT key timestamp 设置过期时间,单位为毫秒
键的生存时间 = 过期时间 - 当前时间
上面的四条命令最终都会转换为PEXPIREAT命令来实际实现
EXPIRE -->PEXPIRE–>PEXPIREAT
EXPIREAT -->PEXPIREAT
还有一种SETEX key "seconds" "value"
专门用于给字符串键设置过期时间
- TTL key 获取key的过期时间(秒)
- PTTL key 获取key的过期时间(毫秒)
三、 过期键删除策略
我们根据过期时间来判断一个键是否过期,如果一个键过期了,那么它什么时候被删除呢?Redis提供三种不同的删除策略:
- 定时删除:在设置键的过期时间同时,创建一个定时器timer,过期时间来临时,就立马删除
- 惰性删除:放任过期时间不管,只有当每次从键空间获取键时,检查是否过期,如果过期就删除该键;没有过期就返回该键
- 定期删除:每隔一段时间,程序对数据库进行一次检查,删除里面的过期键
定时删除的缺点:对CPU时间是不友好的,在过期键较多的情况下,删除过期键可能会占用相当一部分CPU时间,而且创建定时器很耗时,但它又是对内存是最友好的。
惰性删除的缺点:对内存不友好的,因为过期的键会保留在数据库中,只要是过期键不被删除,它所占用的空间就不会释放。
定期删除的难点就是确定删除操作执行的时长和频率。
四、Redis采用的过期删除策略
惰性删除+定期删除
-
惰性删除:
在读写数据库的Redis命令之前会执行调用
expireIfNeeded
函数对输入键进行检查:- 如果输入键已经过期,那么
expireIfNeeded
函数会将输入键删除 - 如果未过期就不动作
而且在之前还要检查键是否存在
- 如果输入键已经过期,那么
-
定期删除:
遍历各个数据库(默认数据库的数量是16),检查当前库中的指定数量的key(默认每个库检查20个key)
- 如果当前库中没有一个key设置了过期时间,直接执行下一个库的检查
- 随机获取一个带有过期时间的键,如果已经过期,就删除它
- 判断是否已达到时间上限,停止
五、RDB对过期key的处理
过期key对RDB没有任何影响
- 从内存数据库持久化数据到RDB文件
- 持久化key之前,会检查是否过期,过期的key不进入RDB文件
- 从RDB文件恢复数据到内存数据库
- 数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)
六、AOF对过期key的处理
过期key对AOF没有任何影响
- 从内存数据库持久化数据到AOF文件:
- 当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令)
- 当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉)
- AOF重写
- 重写时,会先判断key是否过期,已过期的key不会重写到aof文件
【最后欢迎大家来我的博客skiron.xyz来玩,一起学习进步!!!】