redis的过期删除策略+内存淘汰机制
Redis缓存使用的是内存资源,虽然缓存服务器会配置比较高的内存资源,但如果对于Redis中的缓存数据我们不管不顾,内存资源总有耗尽的时候,这时缓存服务器就无法再对外提供服务了。我们要用有限的服务器资源支撑更多的业务服务,就必须要让那些访问频率不高的缓存删除掉,为新的缓存腾出内存空间。
Redis主要通过两种方式相互配合来实现键值的清理,即:过期删除策略和内存淘汰机制。
过期删除策略
如果一个键过期了,那么它什么时候会被删除呢?
- 定时删除:在设置键的过期时间的同时,创建一个定时器(timer ),让定时器在键的过期时间来临时,立即执行对键的删除操作。对内存是最友好的,但会造成性能下降,资源会分配到监控过期时间的功能上。
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。对性能友好,资源充分分配给请求,但内存利用率下降。
- 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地合理使用CPU时间和避免浪费内存空间之间取得平衡。
过期策略对持久化存储的影响
持久化存储,指的是将内存的缓存永久存在磁盘中。也就是说我们的AOF和RDB持久化存储方式。因为该两种方式,将内存中的数据写入磁盘,这时候就需要考虑到我们过期的缓存是否会被写入到磁盘中?如果写入磁盘又是怎么处理的?
- RDB
持久化key之前,会检查是否过期,过期的key不进入RDB文件。
数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)。 - AOF
当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令)。
当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉)。
重写时,会先判断key是否过期,已过期的key不会重写到aof文件。
内存淘汰机制
最大内存的设置是通过设置maxmemory来完成的,格式为maxmemory bytes ,当 Redis 节点分配的内存使用到达最大值以后,为了继续提供服务,Redis 会启动内存淘汰策略,在Redis4.0之前主要是以下六种淘汰策略:
- no-enviction:不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,这种策略下可以保证数据不丢失,它也是 Redis 默认的内存淘汰策略。
- allkeys-random:当内存不足以容纳新写入数据时,随机删除一个或者多个key。
- allkeys-lru:淘汰整个键值中最久未使用的键值,这也就是我们常说的LRU算法。
- volatile-random:随机淘汰设置了过期时间的任意键值。
- volatile-ttl:优先淘汰设置了过期时间中更早过期的键值。
- volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值。