更多详细内从参考这篇博客:
https://blog.csdn.net/D812359/article/details/121872689

1、Redis中的过期删除策略

在Redis中,给key是设置一个过期时间,等到了过期时间的时候,Redis是如何清除这个key的?
这里就要用到Redis中key的过期删除策略。
Redis中使用的是定期删除+惰性删除两种策略一起使用的。

  • 定期删除:每隔一段时间抽取一批key进行检查,检查是否过期,如果过期就进行删除。Redis底层会通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。定期删除相对来说对内存更加友好。
  • 惰性删除:只会在取出key的时候对数据进行过期检查。这样对CPU最友好,但是可能造成太多过期的key没有删除,因此对内存不太友好。

此外还有一种定时删除,不过在Redis中没有使用。定时删除时设置某个key的过期时间的同时,创建一个定时器,让定时器在该过期时间到来时,立即执行删除操作。其优点是通过使用定时器,可以保证过期key可以尽快的被删除,并且释放过期key所占用的内存,缺点是对CPU不友好,当过期key比较多的时候,删除过期key会占用相当一部分CPU资源,对服务器的响应时间和吞吐量造成影响。

仅仅是给key设置过期时间,然后通过key的过期删除策略删除掉key,还是有问题的。因为还是可能存在定期删除+惰性删除漏掉了很多过期key的情况,这样就导致大量过期key堆积在内存里,可能就OutOfMemory了。
那么如何解决这个问题呢?这就要用到Redis提供的内存淘汰机制。

2、Redis中的内存淘汰机制

2.1 什么是内存淘汰机制、要解决什么问题

Redis使用内存保存数据,提高响应速度。但是由于缓存容量优先,当缓存容量达到上限,就需要删除一部分数据挪出空间,这样新数据才可以添加进来。Redis定义了[内存淘汰机制]来解决内存被写满的问题。
内存淘汰机制,也叫缓存替换机制,它需要解决两个问题:

  • 决定淘汰哪些数据;
  • 如何处理哪些被淘汰的数据。

    2.2 有哪些内存淘汰机制

    Redis4.0之前是6种内存淘汰机制,4.0之后增加了两种,所以现在有8中内存淘汰策略。
    4.0之前的六种:
  • noevication:不会淘汰任何数据。这是默认的策略,当内存不足以写入新数据时,不会进行数据淘汰,而是返回错误。
  • allkeys random:从所有的键值对中,任意选择数据进行淘汰。
  • allkeys lru:lru,least recently used。使用LRU算法在所有数据中进行筛选。当内存不足以容纳新写入的数据时,在键空间中,移除最近最少使用的key。 这个比较常用。
  • volatile random:从已设置过期时间的数据集中,任意选择数据淘汰。
  • volatile ttl:从已设置过期时间的数据集中,挑选将要过期的数据淘汰。
  • volatile lru:lru,least recently used。使用LRU算法在设置了过期时间的数据中进行筛选。从已设置过期时间的数据集中,挑选最近最少使用的数据淘汰。

4.0后新增了以下两种:

  • volatile lfu:lfu,least frequently used。使用LFU算法选择设置了过期时间的键值对。即:从已设置过期时间的数据集中挑选最不常用的数据淘汰。
  • allkeys lfu:lfu,least frequently used。使用LFU算法在所有数据中进行筛选。即:当内存不足以容纳新写入数据时,在所有中,移除最不经常使用的key 。

2.3 LRU算法

LRU算法全称Least Recently used,是一种常见的页面置换算法。按照 最近最少使用 的原则来筛选数据,筛选出不常用的数据进行淘汰,最近频繁使用的数据会留在 缓存中。
具体的参考
https://blog.csdn.net/D812359/article/details/121872689

2.4 缓存污染

缓存污染是指,在一些场景下,有的数据被访问到次数非常少,甚至只会访问一次。当这些数据服务完访问请求后,如果还继续留在内存中,会白白占用内存空间,这就是缓存污染。
缓存污染一旦变得验证,就会有大量不再访问的数据留在内存中。如果这些数据占满了缓存空间,我们再向缓存中写入新数据时,就需要先把这些数据逐步淘汰出缓存,这样就会引起额外的内存消耗,进而会相应应用到性能。
如何解决缓存污染呢:
解决方案就是把不会再被访问的数据筛选出来淘汰掉。

2.5 LFU算法

LFU算法全称为 Least Frequenty Used。其核心思想是如果一个数据刚刚被访问,那么这个数据肯定是热数据,还会被再次访问。

3、一些tips

我们在使用 Redis 缓存时,如果数据被修改了,需要在数据修改时就将它写回数据库。
否则,这个脏数据被淘汰时,会被 Redis 删除,而数据库里也没有最新的数据了。