Redis 的过期策略是其内存管理的关键部分,它确保过期的键(设置了 TTL 的键)能够被及时删除以释放内存。
1. 过期时间设置
设置方式
可以在创建键值对时就为其设置过期时间,例如使用
SET
命令的EX
(秒)或PX
(毫秒)选项。如SET key value EX 10
,表示将键 “key” 对应的值设置为 “value”,并且该键将在 10 秒后过期。也可以对已经存在的键使用
EXPIRE
命令来设置过期时间,如EXPIRE key 20
,让键 “key” 在 20 秒后过期。
时间精度
Redis 支持以秒和毫秒为单位设置过期时间,这使得可以精确地控制键的生命周期,以适应不同的应用场景,比如缓存数据的快速更新或者短期的临时数据存储。
2. 定期删除策略
原理
Redis 会不定期地从数据库中随机挑选一些设置了过期时间的键来进行检查。这是通过一个后台线程来完成的,默认情况下,这个线程会每隔 100 毫秒被调用一次。
当被选中的键的过期时间小于当前时间时,Redis 就会将其从数据库中删除。
优点
能够及时地清理过期键,减少数据库中过期数据所占用的空间。例如,对于一些频繁更新且数据时效性要求高的缓存场景,定期删除策略可以保证数据库中的数据不会因为过期键的堆积而变得臃肿。
缺点
这种策略的执行频率是固定的,可能会出现过期键没有及时被处理的情况。比如,在数据库负载很高的时候,后台线程可能无法及时处理过期键,导致过期键在数据库中存在的时间比预期要长。
3. 惰性删除策略
原理
当客户端尝试访问一个键时,Redis 会先检查该键是否设置了过期时间。
如果键已经过期,Redis 会先删除该键,然后再返回结果给客户端。就好像 Redis 对过期键采取了一种 “懒惰” 的态度,只有在键被访问时才去处理它。
优点
这种策略不会主动去扫描键,从而避免了定期删除策略中后台线程可能带来的性能开销。对于存储大量数据但访问频率较低的场景比较适用,因为它不会频繁地对键进行检查。
缺点
过期键可能会在数据库中停留很长时间,直到有客户端访问它。这可能会导致数据库中存在大量已经过期但尚未被清理的键,占用宝贵的存储资源。例如,在一些应用场景中,如果大量过期键长时间存在,可能会因为存储空间不足而导致新的数据写入失败。
4. 两者的结合
Redis 实际上同时采用了定期删除和惰性删除两种策略,以达到一个较好的平衡。
定期删除策略可以主动地清理一部分过期键,防止过期键数量过多。而惰性删除策略则是作为一种补充,确保那些长时间没有被定期删除策略处理的过期键在被访问时能够及时被清理。
这种组合方式使得 Redis 在效率和准确性之间找到了一个相对合理的折中方案,既能保证数据库中过期键不会过度堆积,又不会因为频繁地扫描键而对性能产生过大的影响。
5. 过期时间的更新
重新设置过期时间
在键的过期时间设置之后,可以通过
EXPIRE
命令或者PEXPIRE
命令重新设置键的过期时间。例如,一个键原本还有 30 秒过期,如果在这 30 秒内执行了EXPIRE key 60
,那么该键的过期时间会更新为 60 秒后。
删除过期时间
使用
PERSIST
命令可以移除键的过期时间,使键成为永久键。例如,执行PERSIST key
后,键 “key” 就不再有过期时间的限制。