四、Redis过期删除与内存淘汰

四、Redis过期删除与内存淘汰

1. Redis使用的过期删除策略是什么——惰性删除+定期删除

Redis是可以对key设置过期时间的,因此需要有相应的机制将已过期的键值对删除,而这个工作就是过期键值删除策略

每当我们对一个key设置了过期时间的时候,Redis会把该key带上过期时间存储到一个过期字典中,也就是说「过期字典」保存了数据库中所有key的过期时间

当我们查询一个key时,redis首先检查该key是否存在于过期字典中:

  • 如果不在,则正常读取键值
  • 如果存在,则会获取该key的过期时间,然后与当前的系统时间进行比对,如果比系统时间大,那就没过期,否则判定该key过期

Redis的过期策略是「惰性删除+定期删除」这两种策略的配合使用

1.1 什么是惰性删除策略?

惰性删除的做法是,不主动删除,每次从数据库访问key时,都检测key是否过期,如果过期则删除该key

惰性删除的流程图如下:

img

惰性删除策略优点:

  • 因为每次访问的时候,才会检查key是否过期,所以此策略只会使用很少的系统资源,因此,惰性删除策略对CPU时间最友好

惰性删除策略的缺点:

  • 如果一个key已经过期,而这个key又仍然保存在数据库中,那么只要这个过期key一直没有被访问,它所占用的空间就不会被释放,造成了一定的内存空间浪费。所以惰性删除对内存不友好

1.2 什么是定期删除策略?

定期删除策略的做法是,每隔一段时间「随机」从数据库中取出一定数量的key进行检查,并删除其中的过期key

Redis的定期删除流程:

  1. 从过期字典中随机抽取20个key
  2. 检查者20个key是否已经过期,并删除已过期的key
  3. 如果本轮检查的已过期key的数量超过5个(25%),也就是「已过期key的数量」占比「随机抽取key的数量」大于25%,则继续重复步骤1。如果小于25%,则停止继续删除过期key,等待下一轮检查

可以看到,定期删除是一个循环的流程。那redis为了保证定期删除不会出现循环过度,导致线程卡死现象,为此增加了定期删除循环流程的时间上线25ms

定期删除的流程如下:

img

定期删除策略的优点:

  • 通过限制删除操作执行的时长和频率,来减少删除操作对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 进行数据淘汰策略

可以细分为「在设置了过期时间的数据中进行淘汰」和「在所有数据阀内屋内进行淘汰」两类策略。

  • 在设置了过期时间的数据中进行淘汰:
  1. volatile-random:随机淘汰设置了过期时间的任意键值;
  2. volatile-ttl:优先淘汰更早过期的键值
  3. volatile-lru:淘汰所有设置了过期时间的键值中,最久未使用的键值
  4. volatile-lfu:淘汰所有设置了过期的键值中,最少使用的键值
  • 在所有数据范围内进行淘汰:
  1. allkeys-random:随机淘汰任意键值
  2. allkeys-lru:淘汰整个键值中最久未使用的键值
  3. allkeys-lfu:淘汰整个键值中最少使用的键值

四、Redis过期删除与内存淘汰
http://example.com/2022/12/15/develop/redis/四、Redis过期删除与内存淘汰/
作者
Curious;
发布于
2022年12月15日
许可协议