caffine 本地缓存 和 currenthashmap 缓存 以及 redis 缓存 关系
Caffeine 缓存 和 java集合缓存 以及 redis 缓存 关系先比较前两着,比较显著的区别:1,Caffeine缓存可以设定删除时间等删除条件、ConcurrentMap 代表的只JAVA集合类等只能动态添加保存,除非显示的删除(有可能内存溢出)。2, Caffeine的读写能力显著高于ConcurrentHashMap 。3,ConcurrentMapCacheManager 这一
Caffeine 缓存 和 java集合缓存 以及 redis 缓存 关系
先比较前两着,比较显著的区别:1,Caffeine 缓存可以设定删除时间等删除条件、ConcurrentMap 代表的只JAVA集合类等只能动态添加保存,除非显示的删除(有可能内存溢出)。
2, Caffeine 的读写能力显著高于ConcurrentHashMap 。
3,ConcurrentMapCacheManager 这一类基本都是基于本地内存的缓存,不支持分布式,当然caffeine也是不支持分布式的,著名的支持分布式缓存是redis,,其他的都是应用中的 基于本地应用 的缓存,即本地缓存。
常用的spring Cache :
public enum CacheType {
GENERIC, // 使用的SimpleCacheManager(自己手动指定Cache,可任意类型Cache实现哦)
JCACHE, // 使用org.springframework.cache.jcache.JCacheCacheManager
EHCACHE, // 使用org.springframework.cache.ehcache.EhCacheCacheManager
HAZELCAST, // 使用com.hazelcast.spring.cache.HazelcastCacheManager
INFINISPAN, // 使用org.infinispan.spring.provider.SpringEmbeddedCacheManager
COUCHBASE, // 使用com.couchbase.client.spring.cache.CouchbaseCacheManager
REDIS, // 使用org.springframework.data.redis.cache.RedisCacheManager,依赖于RedisTemplate进行操作
CAFFEINE, // 使用org.springframework.cache.caffeine.CaffeineCacheManager
@Deprecated
GUAVA, // 使用org.springframework.cache.guava.GuavaCacheManager,已经过期不推荐使用了
SIMPLE, // 使用ConcurrentMapCacheManager
NONE; // 使用NoOpCacheManager,表示禁用缓存
}
补充:Memcached,也是高性能、分布式的
简单介绍这几种缓存的特点:
EhCache:一个纯Java的进程内缓存框架,具有快速、精干等特点。因为它是纯Java进程的,所以也是基于本地缓存的。(注意:EhCache2.x和EhCache3.x差异巨大且不兼容)
Hazelcast:基于内存的数据网格。虽然它基于内存,但是分布式应用程序可以使用Hazelcast进行分布式缓存、同步、集群、处理、发布/订阅消息等。(如果你正在寻找基于内存的、高速的、可弹性扩展的、支持分布式的、对开发者友好的NoSQL,Hazelcast是一个很棒的选择,它的理念是用应用服务的内存换取效率,成本较高).
从com.hazelcast.spring.cache.HazelcastCacheManager这个包名中也能看出,是它自己实现的Spring Cache标准,而不是spring-data帮它实现的(类似MyBatis集成Spring),但它凭借自己的足够优秀,让Spring接受了它
Infinispan:基于Apache 2.0协议的分布式键值存储系统,可以以普通java lib或者独立服务的方式提供服务,支持各种协议(Hot Rod, REST, WebSockets)。支持的高级特性包括:事务、事件通知、高级查询、分布式处理、off-heap及故障迁移。 它按照署模式分为嵌入式(Embedded)模式(基于本地内存)、Client-Server(C\S)模式。
Couchbase:是一个非关系型数据库,它实际上是由couchdb+membase组成,所以它既能像couchdb那样存储json文档(类似MongoDB),也能像membase那样高速存储键值对。(新一代的NoSql数据库,国外挺火的)
Redis:熟悉得不能再熟悉的分布式缓存,只有Client-Server(C\S)模式,单线程让它天生具有线程安全的特性。Java一般使用Jedis/Luttuce来操纵~
Caffeine(咖啡因):Caffeine是使用Java8对Guava缓存的重写版本,一个接近最佳的的缓存库(号称性能最好)。Spring5已经放弃guava,拥抱caffeine,它的API保持了近乎和guava一致,但是性能上碾压它。
guava是谷歌Google Guava工具包的,使用非常广泛。Caffeine长江后浪推前浪,性能上碾压了Guava,是它的替代品。
SIMPLE:略
原文链接:https://blog.csdn.net/f641385712/article/details/94982916
下面简单介绍下几种缓存的特点:
1,Caffeine 缓存
1.1 特点
- 自动加载条目到缓存中,可选异步方式
- 可以基于大小剔除
- 可以设置过期时间,时间可以从上次访问或上次写入开始计算
- 异步刷新
- keys自动包装在弱引用中
- values自动包装在弱引用或软引用中
- 条目剔除通知
- 缓存访问统计
1.2 spring-boot 集成caffeine的demo
1.2.1 pom引入
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.0.4</version>
</dependency>
<-- 一般带着这个 !>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
1.2.2 准备cache config配置文件:
下面这段代码相当于在xml配置文件当中声明caffinee cache配置, 即caffiine manager。
@EnableCaching //这个可以加在启动类,即main哪儿
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
// 方案一(常用):定制化缓存Cache
cacheManager.setCaffeine(Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.initialCapacity(100)
.maximumSize(10_000))
// 如果缓存种没有对应的value,通过createExpensiveGraph方法同步加载 buildAsync是异步加载
//.build(key -> createExpensiveGraph(key))
;
// 方案二:传入一个CaffeineSpec定制缓存,它的好处是可以把配置方便写在配置文件里
//cacheManager.setCaffeineSpec(CaffeineSpec.parse("initialCapacity=50,maximumSize=500,expireAfterWrite=5s"));
return cacheManager;
}
}
使用:在代码中直接使用注入即可
@Resource
Cache<Integer, String> deployJobStatusCache;
// deployJobStatusCache.getIfPresent()
特别注释:
1, @Configuration : 指示一个类,或者声明一个或多个@Bean方法,并且可以由Spring容器处理,以便在运行时为这些bean生成BeanDefinition和服务请求。@Configuration 注释的类 类似于于一个 xml 配置文件的存在 ,可以将其理解为一个Xml内容的Java版本, 那么,一些Xml中使用的其他写法可以在其中能直接用。 (https://www.jianshu.com/p/721c76c1529c)
1.3 填充策略
1.3.1 手动填充
此策略,手动将值放入缓存之后再检索。
//step1:初始化
Cache<String, DataObject> cache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES)
.maximumSize(100)
.build();
//get或者put
String key = "A";
DataObject dataObject = cache.getIfPresent(key);
assertNull(dataObject);
cache.put(key, dataObject);
dataObject = cache.getIfPresent(key);
assertNotNull(dataObject);
我们也可以使用 get 方法获取值,该方法将一个参数为 key 的 Function 作为参数传入。如果缓存中不存在该键,则该函数将用于提供回退值,该值在计算后插入缓存中:
dataObject = cache.get(key, k -> DataObject.get(``"Data for A"``));
assertNotNull(dataObject);
assertEquals(``"Data for A"``, dataObject.getData());
get 方法可以原子方式执行计算。这意味着您只进行一次计算 — 即使多个线程同时请求该值。这就是为什么使用 get 优于 getIfPresent。
1.3.2 同步加载
相当于在初始化的时候就缓存赋值,暂不清楚场景!
//step1 : 初始化缓存
LoadingCache<String, DataObject> cache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build(k -> DataObject.get("Data for " + k));
1.3.3 异步加载
和前面差不多,暂不清楚场景。
AsyncLoadingCache<String, DataObject> cache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.MINUTES)
.buildAsync(k -> DataObject.get("Data for " + k));
1.4 回收策略
1.4.1 基于大小回收
这种回收方式假定当超过配置的缓存大小限制时会发生回收。
1.4.2 基于时间回收
这种回收策略是基于条目的到期时间,有三种类型:
-
访问后到期 — 从上次读或写发生后,条目即过期。
.expireAfterAccess(``5``, TimeUnit.MINUTES)
-
写入后到期 — 从上次写入发生之后,条目即过期
.expireAfterWrite(``10``, TimeUnit.SECONDS)
-
自定义策略 — 到期时间由 Expiry 实现独自计算 ——要初始化自定义策略,我们需要实现 Expiry 接口
cache = Caffeine.newBuilder().expireAfter(new Expiry<String, DataObject>() { @Override public long expireAfterCreate( String key, DataObject value, long currentTime) { return value.getData().length() * 1000; } @Override public long expireAfterUpdate( String key, DataObject value, long currentTime, long currentDuration) { return currentDuration; } @Override public long expireAfterRead( String key, DataObject value, long currentTime, long currentDuration) { return currentDuration; } }).build(k -> DataObject.get("Data for " + k));
1.4.3 基于引用回收
还未使用过这种: 可以将缓存配置为启用缓存键值的垃圾回收。为此,我们将 key 和 value 配置为 弱引用,并且我们可以仅配置软引用以进行垃圾回收。
1.5 统计
可以定义统计方式等, 记录缓存的使用情况。
2,redis缓存 (简单介绍)
先说下 redis和caffeine的主要区别和联系:
相同点:
两个都是缓存的方式
不同点:
redis是将数据存储到内存里
caffeine是将数据存储在本地应用里
caffeine和redis相比,没有了网络IO上的消耗
联系:
一般将两者结合起来,形成一二级缓存。使用流程大致如下:
去一级缓存中查找数据(caffeine-本地应用内)
如果没有的话,去二级缓存中查找数据(redis-内存)
再没有,再去数据库中查找数据(数据库-磁盘)
原文链接:https://blog.csdn.net/qsbbl/article/details/107764058
更多推荐
所有评论(0)