本地缓存Caffeine系列(四)

简介: 本地缓存Caffeine系列(四)

和缓存相关的几个核心概念

缓存污染:

指留存在缓存中的数据,实际不会被再次访问了,但又占据了缓存空间。换句话说,由于缓存空间有限,热点数据被置换或者驱逐出去了,而一些后面不用到的数据却反而被留 下来,从而缓存数据命中率急剧下降.

要解决缓存污染的关键点是能尽可能识别出未来热点数据,或者未来更有可能被访问到的数据。由此可见,在高并发的互联网系统中,缓存的命中率是至关重要的指标。

而缓存的命中率的提升,和缓存数据淘汰算法 , 密切相关。

Redis的数据清除策略

在使用Redis时,我们一般会为Redis的缓存空间设置一个大小,不会让数据无限制地放入Redis缓存中。可以使用下面命令来设定缓存的大小,比如设置为4GB:


CONFIG SET maxmemory 4gb

既然Redis设置了缓存的容量大小,那缓存被写满就是不可避免的。当缓存被写满时,我们需要考虑下面两个问题:决定淘汰哪些数据,如何处理那些被淘汰的数据

如果我们设置了Redis的key-value的过期时间,当缓存中的数据过期之后,Redis就需要将这些数据进行清除,释放占用的内存空间。

Redis中主要使用定期删除 + 惰性删除两种数据过期清除策略。

(1)定期删除:redis默认每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果有过期就删除。注意这里是随机抽取的。

为什么要随机呢?你想一想假如 redis 存了几十万个key ,每隔100ms就遍历所有的设置过期时间的key的话,就会给CPU带来很大的负载。


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

(2)惰性删除:

定期删除可能导致很多过期的key 到了时间并没有被删除掉。这时就要使用到惰性删除。在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间并且过期了,是的话就删除。

2、定期删除+惰性删除存在的问题:

如果某个key过期后,定期删除没删除成功,然后也没再次去请求key,也就是说惰性删除也没生效。这时,如果大量过期的key堆积在内存中,redis的内存会越来越高,导致redis的内存块耗尽。那么就应该采用内存淘汰机制。

Redis的缓存淘汰策略:

Redis共提供了8种缓存淘汰策略,其中 volatile-lfu 和 allkeys-lfu 是Redis 4.0版本新增的。

1、noeviction:不进行淘汰数据。一旦缓存被写满,再有写请求进来,Redis就不再提供服务,而是直接返回错误。Redis用作缓存时,实际的数据集通常都是大于缓存容量的,总会有新的数据要写入缓存,这个策略本身不淘汰数据,也就不会腾出新的缓存空间,我们不把它用在 Redis 缓存中。

2、volatile-ttl:在设置了过期时间的键值对中,移除即将过期的键值对。

3、volatile-random:在设置了过期时间的键值对中,随机移除某个键值对。

4、volatile-lru:在设置了过期时间的键值对中,移除最近最少使用(最近最久未使用)的键值对。

5、volatile-lfu:在设置了过期时间的键值对中,移除最近最不频繁使用的键值对, 或者移除 最不经常 使用的键值对

6、allkeys-random:在所有键值对中,随机移除某些key。

7、allkeys-lru:在所有的键值对中,移除最近最少使用(最近最久未使用)的键值对。

8、allkeys-lfu:在所有的键值对中,移除最近最不频繁使用的键值对, 或者移除 最不经常使用的键值对


通常情况下推荐优先使用 allkeys-lru 策略。这样可以充分利用 LRU 这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果你的业务数据中有明显的局部周期性流量( 局部冷热数据区分明显),建议使用 allkeys-lru 策略。
相关文章
|
4月前
|
缓存 算法 Java
Caffeine Cache~高性能 Java 本地缓存之王
Caffeine Cache~高性能 Java 本地缓存之王
324 1
|
1月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
1月前
|
缓存 Java Spring
Java本地高性能缓存实践问题之Caffeine中设置刷新机制的问题如何解决
Java本地高性能缓存实践问题之Caffeine中设置刷新机制的问题如何解决
|
1月前
|
存储 缓存 Java
Java本地高性能缓存实践问题之如何定义Caffeine的缓存
Java本地高性能缓存实践问题之如何定义Caffeine的缓存
|
1月前
|
缓存 Java
Java本地高性能缓存实践问题之Caffeine缓存库中基于时间设置驱逐策略的问题如何解决
Java本地高性能缓存实践问题之Caffeine缓存库中基于时间设置驱逐策略的问题如何解决
|
1月前
|
缓存 Java
Java本地高性能缓存实践问题之使用Caffeine的Cache接口来查找一个缓存元素的问题如何解决
Java本地高性能缓存实践问题之使用Caffeine的Cache接口来查找一个缓存元素的问题如何解决
|
2天前
|
存储 消息中间件 缓存
本地缓存Caffeine系列(三)
本地缓存Caffeine系列(三)
|
2天前
|
存储 缓存 NoSQL
本地缓存Caffeine系列(一)
本地缓存Caffeine系列(一)
|
2天前
|
缓存 算法
本地缓存Caffeine系列(五)
本地缓存Caffeine系列(五)
|
2天前
|
缓存 NoSQL 中间件
本地缓存Caffeine系列(二)
本地缓存Caffeine系列(二)