一,引言
传统缓存存在的问题
二,JVM进程缓存介绍
缓存在日常开发中起到至关重要的作用,由于是存储在内存中的,数据的读取速度是非常快的,能大量减少对数据库的访问,减少数据库的压力。我们把缓存分为两类:
- 分布式缓存,例如Redis
- 优点:存储量更大,可靠性更好,可以在集群间共享
- 缺点:访问缓存有网络开销
- 场景:缓存数据量较大,可靠性要求较高,需要在集群间共享
- 进程本地缓存,例如HashMap,GuavaCache:
- 优点:读取本地内存,没有网络开销,速度更快
- 缺点:存储容量有限,可靠性较低,无法共享
- 场景:性能要求较高,缓存数据量较小
三,Caffeine
Caffeine示例:
@Test
void testBasicOps(){
//创建缓存对象
Cache<String,String> cache=Caffeine.newBuilder().builder();
//存数据
cache.put("gf","name");
//取数据,不存在则返回null
String gf=cache.getIfPresent("gf");
System.out.println("gf="+gf);
//取数据,不存在则去数据库查询,然后会把内容存入缓存
String defaultGf=cache.get("defaultGf",key->{
//这里可以去数据库根据key查询value
return "name2";
});
System.out.println("defaultGf="+defaultGf);
}
缓存驱逐策略: Caffeine提供了三种缓存驱逐策略
-
基于容量: 设置缓存的数量上限
Cache<String,String> cache=Caffeine.newBuilder() .maximumSize(1)//设置缓存大小上限为1 .builder(); -
基于时间:设置缓存的有效时间
Cache<String,String> cache=Caffeine.newBuilder() .expireAfterWrite(Duration.ofSeconds(10))//设置缓存有效期为10秒,从最后一次写入开始计时 .builder(); -
基于引用:设置缓存为软引用或弱引用,利用GC来回收缓存数据,性能较差,不建议使用
在默认情况下,当一个缓存元素过期时,Caffeine不会自动立即将其清除和驱逐,而是在最后一次读或写操作后,或者在空闲时间完成对时效数据的驱逐。