spring5缓存机制之Caffeine

 

前言

Spring5不在支持guava cache,改为使用caffeine缓存。

caffeine cache vs guava cache

     caffeine cache是采用java8编写的一个高性能的缓存库。它的实现与guava cache差不多,很多的方法甚至连注释都一模一样,API也相似,但是它相对于guava cache还是有不少的改进,使得性能高于guava cache。

1、驱逐策略

guava cache------------→ LRU 回收策略

caffeine------------→ Window TinyLfu 回收策略

1.1 LRU

       最近最少使用(LRU)策略之所以成为最受欢迎的方法可能是因为其简洁性、良好的运行时性能,以及一般工作负载下不错的命中率。该策略预测未来的能力受限于存储在高速缓存中的条目历史,LRU倾向于赋予最后访问最高优先级,因为它认为这是最有可能马上被重用的缓存项。

 1.2 Window TinyLfu

       准入机制需要新缓存项的频率要比可能被逐出的缓存项的频率高。准入窗口不会马上进行过滤,而是会给缓存项一个机会来建立起自己的访问频率。这种做法避免了连续未命中的情况,特别适合少数的突发传送发生时,缓存项可能无法维持长期留存的情况。为了保持历史记录的新鲜度,必须周期性或渐进性地使用老化进程,从而把所有计数器减半。

       留存机制使用分段最近最少使用 (SLRU) 策略。缓存项从试用段开始,在随后的接入过程中被提升到保护段(限制在80%容量内)。当保护段满了之后,它就会清除试用段,该做法可能会引起试用缓存项被丢弃。这就保证了重用间隔小的缓存项(最热条目)可以被保留下来,而重用次数较少的缓存项(最冷条目)就成为逐出的候选项。

2、过期策略

       过期通常都是通过每个条目的变量来实现的,过期条目因为容量限制而被逐出。在这种做法中,废弃项目会污染高速缓存,所以有时清道夫线程会被用来周期性地清理高速缓存,回收空余空间。这种策略比用过期时间在O(lg n)优先队列上给条目排序更有效,因为它向用户隐藏了成本,不会在每个读操作和写操作上都施加惩罚。

       Caffeine采取的不同方法是观察哪种固定持续时间的选取次数是最多的。这条限制让我们可以在O(1)时间排序队列上组织条目。活跃持续时间的时长是一个写顺序队列,而限制持续时间的时长是一个存取顺序队列。高速缓存可以复用逐出策略的队列和下面描述的并发机制,所以过期条目就会在缓存维护期被丢弃。

3、并发

       对高速缓存进行并发存取被视为一道难题,因为在大部分策略中,每次存取都是共享状态下的一次写操作。传统方法就是用单一的锁来保护高速缓存。我们也许可以通过把缓存拆分成很多小型独立区域来实现分离锁,从而改进这种方法。但是热门的条目会出现单一锁一样的问题,所以这种方法收效甚微。

       caffeine借用数据库理论中的一个概念,通过提交日志来扩展写操作。它不会马上改变数据结构,而是把更新写在日志中,并且在异步批处理中重放。同样的概念可以通过散列表操作应用在高速缓存上,把操作记录在缓冲区,然后根据策略把重放活动安排在必要的时刻。策略仍然被锁保护着,或者更准确的说,是被尝试锁保护着,但是该策略把争用转移到了日志缓冲区的附加上。

       在caffeine中,高速缓存的读和写使用了不同的缓冲区。存取被记录在了条带环形缓冲区中,在这里,条带被一个线程特定散列挑选出来,当检测到争用时,条带数量就会增加。当环形缓冲区被装满时,一个异步漏(asynchronous drain)就被预定了,后来的缓冲区的附加就被丢弃了,直到腾出空间。因为缓冲区满了,存取未被记录时,缓存的值仍然会被返回给调用程序。策略信息的缺失并没有造成具有意义的影响,因为W-TinyLFU可以鉴别我们希望保留的热门条目。通过使用线程特定散列,而非键的散列,高速缓存通过更平均地扩散负载从而避免了热门条目可能会导致的争用现象。

spring5 中caffeine使用方式

caffeine cache是spring5支持的一种缓存机制之一,性能比concurrentMapCache缓存机制好,而且也要优于guava等缓存机制,
目前了解来看,它是spring支持的性能最好的一种缓存机制。使用方式:
先在pom文件中引入caffeine

<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.6.0</version>
</dependency>

然后在spirng的配置中引入如下配置

<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager"/>

猜你喜欢

转载自blog.csdn.net/dhtx_wzgl/article/details/85229505