前言
我们在使用Redis这个技术的时候,都知道是基于缓存,也就是内存,但是内存其实相对服务器是比较宝贵的资源,假设我们服务器内存是8G的,那么就算这8G全部分配给Redis,当内存不够用时,这时Redis就会删除一些数据,那么这个也就是本文要讲的Redis的过期策略
Redis过期策略
手动设置过期时间 提到Redis的过期,那么我们第一想到的就是给key设置过期时间,设置过期时间操作如下!
EXPIRE key seconds
EXPIREAT key timestamp
PEXPIRE key milliseconds
PEXPIREAT key milliseconds-timestamp
具体使用如下
EXPIRE
192.168.1.20:6379:0>select 1
OK
192.168.1.20:6379:1>set a test
OK
192.168.1.20:6379:1>EXPIRE a 5
1
192.168.1.20:6379:1>get a
test
192.168.1.20:6379:1>get a
NULL
PEXPIRE
192.168.1.20:6379:1>set b hello
OK
192.168.1.20:6379:1>EXPIREAT b 1638803793
1
192.168.1.20:6379:1>get b
hello
192.168.1.20:6379:1>get b
NULL
思考 我们给Redis中的key设置了过期时间(以上两种方式),Redis内部是怎么实现数据删除的呢, Redis底层是采用定期删除+惰性删除的模式!
惰性删除 惰性删除是被动的,也就是当客户端来获取某个key的时候,Redis会先检查一下这个key是否过期了,如果过期了那么就会将这个key删除掉,从而保证过期的可以一定会被删除! 优点:对CPU最友好,只在操作当前可以的时候进行检查,删除目标仅限于当前操作的key不会在与本次操作不相干的可以上浪费CPU开销
定时删除 定时删除并不是Redis默认采用的过期策略,但是也是提供了这么一种实时性搞得过期策略,当我们给key设置过期时间的同时Redis会创建一个定时器,为这个可以创建一个定时器,让定时器在key过期时间来临时,立刻执行删除当前可以的操作! 优点:对内存释放最友好,可以及时释放过期的key所占用的内存 缺点:对CPU不是很友好,特别是在大量设置过期key的时候,删除key会占用相当一部分CPU的开销,同时在内存不紧张的时候,CPU紧张的情况下,将CPU用在删除和当前任务不相干的过期key上,会对服务器响应时间和吞吐量造成影响!
定期删除 所谓定期删除,是指Redis默认每隔100毫秒就随机抽取一些(20个)设置过期时间的key,检查这些被抽取到的key是否过期,如果过期就删除,注意这里是随机抽取一些key检查是否过期的 ,如果检查所有的可以那么对CPU的开销会很大的,加入Redis给10万个key都设置了过期时间,每隔100毫秒都检查所有的,那么这种肯定是不行的,所以这里Redis是采用默认时间随机抽取一些key检查是否过期,但是这里就会有问题,假设我们过期的key没被随机抽取到,那么也就不会被删除,那么也就能获取到数据,这时Redis的惰性删除就派上用场了! 这种定期删除的过期策略是对上述两种策略的一个折中方案,可以通过数据情况配置定期频率和时长 优点:
- 通过设置删除操作的时长和频率,来减少删除对CPU开销,这也是优化定时删除的缺点
- 定期删除过期key这是优化惰性删除的缺点
缺点:
- 对内存及时删除不如定时删除
- 对没必要的CPU开销不如惰性删除
问题思考 假设我们Redis中存在大量设置时间的key,而且已经过期了,但是服务器内存占用一直还是很高,那么这是因为单靠定期删除是随机的,就是那些过期的key数据没被随机扫描到,所以这些过期的数据还保留在内存中,除非获取一下key走惰性删除掉这些已经过期的数据,那么说到这里我们Redis中不单数存储设置过期时间的key,当然还有更多的没有设置过期时间的key,那这些没有设置过期时间的key占用内存过大后也是有一套删除策略的,那么这个被称为Redis内存淘汰策略!Redis内存淘汰策略
持久化对过期key处理
我们知道Redis提供两种持久化方式,AOF和RDB两种,默认采用RDB方式持久化,那么二者对于过期key的处理如下!
RDB对过期key的处理 从内存持久化到RDB:在持久化到RDB前会先检查当前key是否过期,如果过期,那么不写入 从RDB到内存:在Redis启动读取RDB快照时,加载key时会先检查是否过期,如果过期,那么不写入
AOF对过期key的处理 从内存持久化到AOF:
- 当key过期后,还没有被删除时,此时会被持久化到AOF中
- 当key过期后,在发生删除操作是,Redis会先AOF文件追加一条删除命令,删除过期的可以
AOF重写时,会先判断key是否过期,已经过期的key则不会写入AOF中
|