四、Redis过期删除与内存淘汰
四、Redis过期删除与内存淘汰
1. Redis使用的过期删除策略是什么——惰性删除+定期删除
Redis是可以对key设置过期时间的,因此需要有相应的机制将已过期的键值对删除,而这个工作就是过期键值删除策略
每当我们对一个key设置了过期时间的时候,Redis会把该key带上过期时间存储到一个过期字典中,也就是说「过期字典」保存了数据库中所有key的过期时间
当我们查询一个key时,redis首先检查该key是否存在于过期字典中:
- 如果不在,则正常读取键值
- 如果存在,则会获取该key的过期时间,然后与当前的系统时间进行比对,如果比系统时间大,那就没过期,否则判定该key过期
Redis的过期策略是「惰性删除+定期删除」这两种策略的配合使用
1.1 什么是惰性删除策略?
惰性删除的做法是,不主动删除,每次从数据库访问key时,都检测key是否过期,如果过期则删除该key
惰性删除的流程图如下:
惰性删除策略优点:
- 因为每次访问的时候,才会检查key是否过期,所以此策略只会使用很少的系统资源,因此,惰性删除策略对CPU时间最友好
惰性删除策略的缺点:
- 如果一个key已经过期,而这个key又仍然保存在数据库中,那么只要这个过期key一直没有被访问,它所占用的空间就不会被释放,造成了一定的内存空间浪费。所以惰性删除对内存不友好
1.2 什么是定期删除策略?
定期删除策略的做法是,每隔一段时间「随机」从数据库中取出一定数量的key进行检查,并删除其中的过期key
Redis的定期删除流程:
- 从过期字典中随机抽取20个key
- 检查者20个key是否已经过期,并删除已过期的key
- 如果本轮检查的已过期key的数量超过5个(25%),也就是「已过期key的数量」占比「随机抽取key的数量」大于25%,则继续重复步骤1。如果小于25%,则停止继续删除过期key,等待下一轮检查
可以看到,定期删除是一个循环的流程。那redis为了保证定期删除不会出现循环过度,导致线程卡死现象,为此增加了定期删除循环流程的时间上线25ms
定期删除的流程如下:
定期删除策略的优点:
- 通过限制删除操作执行的时长和频率,来减少删除操作对CPU的影响,同时也能删除一部分过期的数据减少了过期键堆空间的无效占用
定期删除策略的缺点:
- 难以确定删除执行的时长和频率。如果执行的太频繁,就会对CPU不友好,如果执行的太少那又和惰性删除一样了,过期key的空间不会及时得到释放
在真正使用的时候,redis选择「惰性删除+定期删除」这两种策略配合使用
2. Redis持久化时,对过期的键会如何处理?
redis持久化分为AOF和RDB两种方式,下面分别来看过期键在这两种格式中呈现的状态
2.1 RDB
RDB文件分为两个阶段,RDB文件生成阶段和加载阶段
- RDB文件生成阶段:从内存状态持久化成RDB文件的时候,会对KEY进行过期检查,过期的「键」不会被保存到新的RDB文件中,因此redis中的过期键不会对生成新RDB文件产生任何影响
- RDB加载阶段:RDB加载阶段时,如果redis是主服务器模式运行的话,程序会对文件中保存的键进行检查,过期键「不会」被载入到数据库中,所以过期键不会对载入RDB文件的主服务器造成影响
2.2 AOF
AOF文件分为两个阶段,AOF文件写入阶段和AOF文件重写阶段
- AOF文件写入阶段:当Redis以AOF模式持久化时,如果数据库某个过期键还没被删除,那么AOF文件会保留这个过期键,当此过期键被删除后,redis会向AOF文件追加一条DEL命令来显式地删除该键值
- AOF重写阶段:执行AOF重写时,会对redis中的键值进行检查,已过期的键不会被保存到重写后的AOF文件中,因此不会对AOF重写造成任何影响
3. Redis主从模式中,对过期键会如何处理?
当Redis运行在主从模式下时,从库不会进行过期扫描,从库对过期的处理是被动的。也就是即使从库中的key过期了,如果有客户端访问从库时,依然可以得到key对应的值,像未过期的键值对一样返回
从库的过期键处理依靠主服务器控制,主库在key到期时,会在AOF文件里加一条del指令,同步到所有的从库,从库执行这条del指令来删除过期的key
4. Redis的内存满了,会发生什么?——内存淘汰策略
在Redis的运行达到了某个阈值,就会触发内存淘汰机制,这个阈值就是我们设置的最大运行内存,在redis配置文件中可以找到,maxmemory
4.1 Redis内存淘汰策略有哪些?
redis的淘汰策略总共有8种,8种策略大体分为「不进行数据淘汰」和「进行数据淘汰」两类策略
4.1.1 不进行数据淘汰策略
noevicition:它表示当运行内存超过最大设置内存时,不淘汰任何数据,而是不再提供服务直接返回错误
4.1.2 进行数据淘汰策略
可以细分为「在设置了过期时间的数据中进行淘汰」和「在所有数据阀内屋内进行淘汰」两类策略。
- 在设置了过期时间的数据中进行淘汰:
- volatile-random:随机淘汰设置了过期时间的任意键值;
- volatile-ttl:优先淘汰更早过期的键值
- volatile-lru:淘汰所有设置了过期时间的键值中,最久未使用的键值
- volatile-lfu:淘汰所有设置了过期的键值中,最少使用的键值
- 在所有数据范围内进行淘汰:
- allkeys-random:随机淘汰任意键值
- allkeys-lru:淘汰整个键值中最久未使用的键值
- allkeys-lfu:淘汰整个键值中最少使用的键值