【Caffeine缓存】如何使用Caffeine存入缓存和查询缓存?本地缓存之王Caffeine简单快速上手
Caffeine如何写入缓存?如何查询缓存?Caffeine如何设置缓存有效时间?Caffeine如何设置缓存大小上限?看完本篇文章,你会得到答案。
1. Caffeine介绍
Caffeine 是用 Java 8 编写的一个 Key-Value 本地缓存库,是 Spring 默认选择的本地缓存库,缓存数据存储在内存中。与 Redis 不同的是,Redis 是分布式缓存。
Caffeine 因为使用了先进的 Window-TinyLFU 缓存淘汰算法,提供了一个近乎最佳的命中率。综合了 LRU 和 LFU 算法的长处。成为当之无愧的本地缓存之王。
2. Caffeine快速上手
2.1 导入依赖
使用前,首先导入 Caffeine 的 Maven 坐标。
<!-- 本地缓存之王Caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
由于 Caffeine 是 Spring 默认的本地缓存,因此可以不指定具体的版本,版本由 Spring Boot 管理。
2.2 基本使用
1)简单写入和查询
下面列出了 Caffeine 常用方法:增、查。
方法 | 作用 |
---|---|
newBuilder().build() | 构建 Caffeine 缓存对象 |
put(T k, R v) | 写入缓存 |
getIfPresent(Object key) | 查询缓存,如果存在则返回;如果不存在则返回 null |
get(K var1, Function<? super K, ? extends V> var2) | 以 var1 为 Key ,先在缓存中查询数据,如果命中则直接返回;如果未命中则根据 var1 去数据库中查询,如果查到则存入缓存再返回。第二个入参是函数式变量,里面写数据库查询代码,可以使用 Lambda 编程 |
下面展示了上述方法的一段代码示例。
@SpringBootTest
public class CaffeineTest {
@Test
public void testSetCache() {
// 1.创建Caffeine缓存构建器builder,Key和Value均为String类型
Cache<String, String> cache = Caffeine.newBuilder().build();
// 2.写入缓存
cache.put("name", "岳飞");
// 3.查询缓存
String name = cache.getIfPresent("name");
System.out.println("name = " + name);
// 4.先去Caffeine中查询,如果未命中,则根据Key去数据库查询,并会自动将数据写入Caffeine再返回
String hero = cache.get("hero", key -> {
// 4.1 根据Key去数据库查询,使用了函数式编程
// 数据库查询代码段...
return "秦桧";
});
System.out.println("hero = " + hero);
}
}
2)简单驱逐策略
由于 Caffeine 缓存数据存储在内存中,而内存相比硬盘而言空间相对有限,因此需要及时把不重要的缓存数据删除,称为【驱逐】(Evict) ,又称【缓存淘汰】。
如何衡量一个缓存数据是否【重要】?Caffeine 里采用了最先进的 Window-TinyLFU 算法进行驱逐。本章主要讨论的是 Caffeine 实战,对 Window-TinyLFU 算法感兴趣的同学可以参考我写的《Caffeine缓存淘汰算法Window-TinyLFU详解》,不在此过多赘述。
为了简单起见,这里只展示两个最简单的缓存驱逐策略:基于空间驱逐和基于时间驱逐。
首先来看基于空间的驱逐策略。意思是给 Caffeine 设置固定的缓存数量上限,当缓存中的数据超过大小限制时,最先进入缓存的数据被驱逐 (先进先出) 。这部分的设置在构建 Caffeine 构建器 builder 时配置,下面是一段代码示例。
@Test
public void testEvictCache() throws InterruptedException {
// 1.创建Caffeine Cache对象
Cache<String, String> cache = Caffeine.newBuilder()
// 1.1 设置缓存大小上限为1,即只能缓存1个数据
.maximumSize(1)
.build();
// 2.缓存3个数据,故意超出上限
cache.put("id1", "赵构");
cache.put("id2", "秦桧");
cache.put("id3", "岳飞");
// 3.延迟10ms,给负责驱逐的线程一点时间
Thread.sleep(10L);
// 4.查询这3个数据
System.out.println("id1 = " + cache.getIfPresent("id1"));
System.out.println("id2 = " + cache.getIfPresent("id2"));
System.out.println("id3 = " + cache.getIfPresent("id3"));
}
输出:
id1 = null
id2 = null
id3 = 岳飞
上面第 16 行代码,说明 Caffeine 驱逐缓存是需要一定时间的。如果不给驱逐线程留时间,则会全部 3 个数据都查出来。
最后来看基于时间的驱逐策略。意思是给每个缓存数据设置一个【有效时间】(time to live, TTL) ,超时则被驱逐。使用方法与上面相似,下面是使用代码示例。
@Test
public void testTTLBasedEvictCache() throws InterruptedException {
// 1.创建Caffeine对象
Cache<String, String> cache = Caffeine.newBuilder()
// 1.1 设置有效时间为1s
.expireAfterWrite(1, TimeUnit.SECONDS)
.build();
// 2.缓存数据
cache.put("id1", "赵构");
// 3.马上查询,可以看到数据
System.out.println("id1 = " + cache.getIfPresent("id1"));
// 4.故意延迟1.2s,验证缓存过期
Thread.sleep(1200L);
// 5.再次查询缓存,发现已过期
System.out.println("id1 = " + cache.getIfPresent("id1"));
}
输出:
id1 = 赵构
id1 = null
以上就是 Caffeine 缓存最基本的使用方法了,希望对你有帮助。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)