更多详细内从参考这篇博客:
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定义了[内存淘汰机制]来解决内存被写满的问题。
内存淘汰机制,也叫缓存替换机制,它需要解决两个问题:
- 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 删除,而数据库里也没有最新的数据了。