我们一般都用内存作为缓存,但是内存是无限的吗?当然不是,内存是很宝贵且有限的自然。

可能一台机器也就十几G的内存,但是却可以挂几个T,十几个T的硬盘空间,Reids主要是基于内存做高性能,高并发的读写操作的。

那么问题来了?既然内存时有限的,比如Redis就只给分配了10G的内存,你却要往里硬怼20G的数据,会咋办?毫无疑问,当然会被干掉10G的数据了,那问题又来了,干掉那些数据?保留那些数据?我们当然希望干掉那些不常用的,保留常用的数据了。

所以说,这是缓存的一种基本概念,数据是会过期的,要么你自己设置过期时间,要么在满足某些条件下Redis帮你干掉。

如果自己设置了过期时间,那你知道Redis是怎么给你弄过期的吗?什么时候被删除的?

比如我们在set key时可以给定一个expire time就是过期时间,比如指定这个key的过期时间为1小时?10分钟? 这个很有用的,我们自己控制缓存的存活时间。

假如你设置了一批key只能存活1小时,那么一小时后,Redis是如何对这一批key进行删除的尼?请往下看!

定期删除+惰性删除

所谓定期删除指的是Redis默认会每隔一定时间(默认100ms)就会抽取一批设置了过期时间的key来检测是否过期,过期就删除。假设你Redis存放了100万key都设置了过期时间,你每隔几百毫秒,就检查100万key,那Reids基本就挂了, cup负载会飙升,都消耗在你检测过期key上了。
注意⚠️!这里可不是每隔100ms就遍历所有的设置了过期的key,那样将是一场性能上的灾难。实际上Redis是每隔100ms随机的抽取一部分设置过期时间的key来检测和删除。

但是问题来了?? 定期删除可能会导致一部分过期了的key时间到了却并没有被删除,怎么办?别着急,这就该我们的惰性删除登场了。

惰性删除,就是你在获取某个Key时Redis会先检测一下,这个key是否设置了过期时间?如果设置了过期时间那么是否过期?过期就删除。

通过上述两种手段基本上可以保证过期的key一定会被干掉。

但是实际问题比这复杂多了,比喻定期删除漏掉了很多过期的key,然后也没及时的去查也就没有走惰性删除,此时会怎么样?大批的过期key躺在内存了,导致Redis内存很快别被耗尽,咋办?咋办?咋办?

别急! 这种情况会走内存淘汰机制

内存淘汰

如果Redis的内存占用过多的时候,此时Redis会进行内存淘汰,如何淘汰?会有如下几种淘汰策略。

  • noeviction: 当内存不足以容纳新写入的数据时,新写入数据时会报错。这个一般不会有人使用,感觉太🤢人了。
  • allkeys-lru:当内存不足以容纳新写入的数据时,在键空间中,移除最近最少使用的key.(这也是我们经常使用的策略)
  • allkes-random:当内存不足以容纳新写入的数据时,在键空间中,随机移除某个key。(这个正常人都不会使用吧,为啥要随机?肯定移除最近最少使用的key呀)
  • volatile-lru:当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,移除最近最少使用的key。(这个一般也不太合适)
  • volatile-random:当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,随机移除某个key。
  • volatile-ttl:当内存不足以容纳新写入的数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。(这个也不合理)

到这Redis的过期策略基本介绍完了。也就三把 🔪 🔪 🔪

🔪定期删除+🔪惰性删除+🔪内存淘汰(最常用的allkeys-lru)


阅历笔记
279 声望37 粉丝

喷泉之所以漂亮是因为她有了压力;