定时删除:

在这是键的过期时间的同时,创建一个定时器 Timer,让定时器在键过期时间来临时立即执行对过期键的删除。
对内存友好,对 CPU 不友好。如果过期删除的键比较多的时候,删除键这一行为会占用相当一部分 CPU 性能,会对 Redis 的吞吐量造成一定影响

惰性删除:

键过期后不管,每次读取该键时,判断该键是否过期,如果过期删除该键返回空。
对 CPU 友好,内存不友好。如果很多键过期了,但在将来很长一段时间内没有很多客户端访问该键导致过期键不会被删除,占用大量内存空间。
**

定期删除:

每隔一段时间对数据库中的过期键进行一次检查。
是定时删除和惰性删除的一种折中。每隔一段时间执行一次删除过期键的操作,并且限制删除操作执行的时长和频率。
Redis的具体的操作如下:

  • Redis 会将每一个设置了 expire 的键存储在一个独立的字典中,以后会定时遍历这个字典来删除过期的 key。除了定时遍历外,它还会使用惰性删除策略来删除过期的 key。
  • Redis 默认每秒进行十次过期扫描,过期扫描不会扫描所有过期字典中的 key,而是采用了一种简单的贪心策略。
    ①从过期字典中随机选择 20 个 key;②删除这 20 个 key 中已过期的 key;③如果过期 key 比例超过 1/4,那就重复步骤①。
  • 同时,为了保证在过期扫描期间不会出现过度循环,导致线程卡死,算法还增加了扫描时间上限,默认不会超过 25ms。

redis采用的是定期删除+惰性删除策略

为什么不用定时删除策略?

定时删除,用一个定时器来负责监视key,过期则自动删除,虽然内存及时释放,但是十分消耗cpu资源,在高并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用定时删除策略。

定期删除+惰性删除是如何工作的?

定期删除,redis默认每隔100ms随机抽取进行检查,是否有过期的key,有过期的key则删除,但是如果单单才用定期删除,那么还是会存在很多的过期key没有被删除,所以惰性删除就起作用了,惰性删除也就是在获取某个key的时候,redis会检查下,这个key如果设置了过去时间并且已经过期,那么这个key就会被删除

采用定期删除+惰性删除就没有问题了吗?

不是的,如果定期删除没删除key,然后你也没去请求key,这样redis的内存会越来越高,那么就应该采用缓存淘汰机制。
在redis.conf配置文件有一行配置

  1. maxmenory-policy volatile-lru

该配置就是配内存淘汰策略的
volatile-lru:从已设置过期的数据集中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
allkeys-random:从数据集中随机挑选任意数据淘汰
no-enviction:禁止驱逐数据,新写入操作会报错

如果没有设置expire的key,不满足先决条件,那么和volaltile-lru、volaltile-random和volaltile-ttl策略行为,和noeviction基本一致