一级与二级、三级缓存基本的概念
jvm缓存(一级缓存)
优点:查询速度非常快
缺点:
1.jvm内置缓存与业务申请内存没有解耦,有可能会发生内存溢出问题
2.缓存容量比较少的
3.jvm内置缓存集群的话 需要考虑数据一致性问题
4.jvm内存缓存 jvm服务器重启时 内存数据都没有了
缓存—当缓存满了 缓存淘汰策略 将近期没有使用的缓存 自动清理掉
jvm内置缓存:EhCache 、OSCache 底层就是一个map集合
触发gc回收时 ,stw 短暂暂停用户线程 会形式短暂卡顿问题
将数据存放在内存—将对象序列化 json
从内存中读取数据到程序中(反序列化 json数据变成对象)
将数据存放在内存、redis(内存)、数据库
redis缓存(二级缓存)
优点:查询数据存放内存中,缓存数据非常多 redis集群
缺点:但是查询过程中 需要经过网络 IO操作
数据库(三级)
优点:存放数据内容比redis更多 更加可靠
缺点:数据直接持久化在硬盘中,查询效率偏低 会经过磁盘io
在实际开发项目,为了减少数据库的访问压力,我们都会将数据缓存到内存中,比如:Redis(分布式缓存)、EhCache(JVM内置缓存)。
缓存级别越小缓存内容越少,缓存级别越大缓存内容越多;
例如在早期项目中,项目比较小可能不会使用Redis作为缓存,使用JVM内置的缓存框架,项目比较大的时候开始采用Redis分布式缓存框架,这时候需要设计一级与二级缓存。
缓存机制
JVM内置缓存:将数据缓存到当前JVM中
缺陷:占用当前JVM内存空间,可能造成内存溢出问题;集群很难保证各个节点之间数据同步问题。
举例:EhCache,OsCache底层原理采用HashMap实现 淘汰策略
分布式缓存Redis:数据能够共享
装饰模式概念
不改变原有的代码实现增强。Mybatis、Hibernate二级缓存都属于开发者自己去实现扩展的功能。
装饰模式与代理模式区别
代理模式对目标对象(目标方法)实现增强;
装饰模式对装饰对象实现增强,不能改变原有代码。
基于HashMap手写Jvm内置缓存
import java.util.HashMap;
public class JvmMapCacheUtils<V> {
private static HashMap<String, String> cacheMap = new HashMap<String, String>();
public static void putEntity(String key, Object object) {
cacheMap.put(key, JSONObject.toJSONString(object));
}
public static <T> T getEntity(String key, Class<T> t) {
String json = cacheMap.get(key);
JSONObject jsonObject = JSONObject.parseObject(json);
return JSONObject.parseObject(json, t);
}
public static void main(String[] args) {
UserEntity userEntity = new UserEntity(1, "mayikt", 22);
JvmMapCacheUtils.putEntity("user1", userEntity);
UserEntity user = JvmMapCacheUtils.getEntity("user1", UserEntity.class);
System.out.println(user);
}
}