传统缓存
用户请求 ——> tomcat ——> Redis <——> DB
tomcat的并发远远低于Redis,tomcat的并发就成为当前业务的瓶颈了
多级缓存
用户请求 ——> nginx ——> nginx本地缓存 ——> redis ——> JVM缓存 ——>DB
nginx本地缓存如果有结果直接返回给用户。
如果nignx本地缓存没有,就去找redis找缓存。
如果Redis没有缓存就去JVM找缓存。
实在没有数据,就去DB查询。如果查询不到,塞入可过期的Redis假数据,防止暴力攻击DB
了解分布式缓存与进程本地缓存
分布式缓存:Redis
优点
- 可共享数据
- 高可用(集群方案)
缺点
- 维护性高
本地缓存:HashMap
优点
- 内存读取,无网络开销
缺点
- 多个服务之前无法共享数据
- 宕机就意味数据丢失
认识Caffeine 本地缓存
官网:https://github.com/ben-manes/caffeine/wiki/Home-zh-CN
Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。可以理解成一个高性能的Map结构
Caffeine提供了三种缓存驱逐策略
- 基于容量:创建Caffeine对象时设置缓存数量的上香
- 基于时间:创建Caffeine对象时设置缓存的有效期
- 基于引用:设置缓存为软引用或弱引用,利用GC来回收。性能较差
注意:Caffeine设置的元素过期时,不是立马删除,是等下一次读写操作时或系统空闲时完成对数据的清理!
For Java 11 or above, use 3.x
otherwise use 2.x
.
试验:Caffeine的API通过先查缓存,缓存没有才查询DB
配置类
代码语言:javascript复制import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
@Configuration
public class CaffeineConfig {
@Bean
public Cache<String, String> 交由Spring管理Caffeine对象() {
return Caffeine.newBuilder()
.initialCapacity(100) // 设置初始化大小是100
.maximumSize(10) // 设置缓存最多存储10个
.expireAfterWrite(Duration.ofSeconds(60)) // 60秒后标记为可清除
.build();
}
}
操作代码:Caffeine的API通过先查缓存,缓存没有才查询DB
代码语言:javascript复制 @Autowired
private Cache<String, String> cacheA;
@Test
public void Caffeine() {
String name = cacheA.getIfPresent("name"); // 如果没有name则返回null
cacheA.put("name", "张三");
String newName = cacheA.getIfPresent("name"); // 如果没有name则返回null
// 新用法,如果缓存没有,就会执行Lambda表达式的内容。
String age = cacheA.get("age", key -> {
// 模拟DB查询,然后插入数据
String db_Data = "10";
return db_Data; // return的数据,就被缓存了,同时返回此数据
});
System.out.println("Debug在这里,看一下变量name、newName、age");
}
特殊说明: 以上文章,均是我实际操作,写出来的笔记资料,不会盗用别人文章!烦请各位,请勿直接盗用!转载记得标注来源!