Redis 设置键过期时间的命令
/**
* 将key 的值设置为 value,并将 key 的过期时间设为 seconds (以秒为单位)。
* 只适用于String对象
*/
SETEX key seconds value
/**
* 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,
* 而不是像 SETEX 命令那样,以秒为单位。
* 只适用于String对象
*/
PSETEX key milliseconds value
//将键 key 的生存时间设置为 seconds 秒
EXPIRE key seconds
//将键 key 的生存时间设置为 milliseconds 毫秒
PEXPIRE key milliseconds
//将键 key 的过期时间设定为 timestemp 指定的秒数时间戳
EXPIREAT key timestemp
//将键 key 的过期时间设定为 milliseconds-timestemp 指定的秒数时间戳
PEXPIREPAT key milliseconds-timestemp
复制代码
以上六种设置键过期的方式,其中 SETEX
和 PSETEX
两个命令只适用于字符串对象,其他4个命令适用于所有键类型。虽然有很多不同的命令可以设置键过期,但是最终其他的命令都会被转为通过 PEXPIREPAT
命令实现。
过期键删除策略
通过设置键的过期时间,可以判断某个时间点一个键是否过期。对于已过期的键,还需要将其删除,删除的策略有三种:
- 定时删除:在设置键的过期时间时,创建一个定时器,让定时器在键过期的时候,立即执行对键的删除操作。
- 优点:对内存最友好,应删尽删
- 缺点:对CPU不友好,在过期键较多的情况下,定时器会占用太多的CPU资源
- 惰性删除:放任过期键不管,每次从键空间中获取键时,都检查取得的键是否过期,如果过期则将其删除并返回
nil
,如果键不过期则返回键。- 优点:对CPU友好,只在用到键的时候才判断是否过期
- 缺点:对内存不友好,如果一个过期键没有再被用到,也就会一直留在内存中
- 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。
- 对定时删除和定期删除进行整合和折中,同时减轻CPU和内存的消耗
- 难点:如何确定删除操作执行的时长和频率,执行得太频繁或者执行时间太长会退化为定时删除,执行得太少则退化为惰性删除
Redis 过期键删除策略
Redis 中采用惰性删除和定期删除配合的策略,实现合理使用CPU时间和避免浪费内存空间之间取得平衡。
Redis 中,对于设置了过期时间的键,每次读写键时都会调用
expireNeeded
函数判断键是否过期。惰性删除策略模式如下:
定期删除策略
- 每隔一段时间,Redis会用规定的时间片段,从指定数据库中取出一定数量的键进行检查是否过期
- 使用
current_db
记录当前的检查的数据库(一个Redis服务器中可以有多个数据库,通过select
命令指定当前使用的数据库)- 当所有数据库都被检查一遍之后,
current_db
被设置为0,下一次从0号数据库开始重新检查