天天看点

【缓存】通用缓存

Spring Cache是什么?

Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)

【缓存】通用缓存

Spring Cache的好处

1,提供基本的Cache抽象,方便切换各种底层Cache; 

2,通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成; 

3,提供事务回滚时也自动回滚缓存; 

4,支持比较复杂的缓存逻辑;

Spring Cache支持的缓存类型

【缓存】通用缓存
@Bean
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
    return new EhCacheCacheManager(ehCacheCacheManager);
}      

Spring Cache常用的缓存注释

【缓存】通用缓存

@EnableCaching:

标记注解 @EnableCaching,开启缓存,并配置Redis缓存管理器。@EnableCaching 注释触发后置处理器,检查每一个Spring bean 的 public 方法是否存在缓存注解。如果找到这样的一个注释,

自动创建一个代理拦截方法调用和处理相应的缓存行为。 

缓存@Cacheable

根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。

属性值如下:

【缓存】通用缓存

缓存@CachePut

使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。

缓存@CacheEvict

【缓存】通用缓存

缓存应用流程

  • 通过缓存提供者CachingProvider得到缓存管理器CacheManager;
  • 缓存提供者可以管理多个缓存管理器;
  • 每个缓存管理器管理特定类型的缓存;比如:CacheManager1管理redis缓存、CacheManager2管理memcache缓存;
  • 缓存管理器用来管理缓存Cache;
  • 一个缓存管理器管理多个缓存;比如:Cache1用来保存员工数据、Cache2用来缓存部门数据;
  • 缓存中保存多条数据,每一条数据是一个键值对;
  • Cache接口中提供了一些api,用来对数据进行增删改查操作;
【缓存】通用缓存

什么样的数据适合放入缓存

什么样的数据需要放进缓存呢?把数据放入缓存,有三个标准:

  •  数据量不大
  •  访问频率高
  •  数据更改频率低

常用的本地缓存

本地缓存 介绍
Caffeine

​Caffeine​

​是使用​

​Java8​

​对​

​Guava​

​缓存的重写版本,在​

​Spring Boot 2.0​

​中将取代​

​Guava​

​,基于​

​LRU​

​算法实现,支持多种缓存过期策略。
ehcache 是一个纯​

​Java​

​的进程内缓存框架,具有快速、精干等特点,是​

​Hibernate​

​中默认的​

​ CacheProvider​

​。
GuavaCache

​Google Guava​

​工具包中的一个非常方便易用的本地化缓存实现,基于​

​LRU​

​算法实现,支持多种缓存过期策略。

常用的本地缓存测试比较

测试逻辑:

  •  构建Cache,load方法为简单的字符串拼接
  •  将250000个字符串加载到cache后,启动任务线程,预热10s后,开始计时,统计每10秒的count,共6轮,最后统计每轮中的每秒平均值

测试结果:

【缓存】通用缓存
(1) 6个线程纯读:
【缓存】通用缓存
(2) 4个线程读+2个线程写:
【缓存】通用缓存

压测对比

运行环境:MacBook

Pro i7-4870HQ CPU @ 2.50GHz (4 core) 16 GB 

读操作

在这个基准测试中,8个线程同时从配置了最大大小的缓存中读取。

【缓存】通用缓存

写操作

在这个基准测试中,8个线程同时写入一个配置了最大大小的缓存。

【缓存】通用缓存

Unbounded ops/s (8 threads) ops/s (16 threads)
ConcurrentHashMap (v8) 560,367,163 1,171,389,095
ConcurrentHashMap (v7) 301,331,240 542,304,172
Bounded
Caffeine 181,703,298 382,355,194
ConcurrentLinkedHashMap 154,771,582 313,892,223
LinkedHashMap_Lru 9,209,065 13,598,576
Guava (default) 12,434,655 10,647,238
Guava (64) 24,533,922 43,101,468
Ehcache2_Lru 11,252,172 20,750,543
Ehcache3_Lru 11,415,248 17,611,169
Infinispan_Old_Lru 29,073,439 49,719,833
Infinispan_New_Lru 4,888,027 4,749,506

Unbounded ops/s (8 threads) ops/s (16 threads)
ConcurrentHashMap (v8) 60,477,550 50,591,346
ConcurrentHashMap (v7) 46,204,091 36,659,485
Bounded
Caffeine 55,281,751 48,295,360
ConcurrentLinkedHashMap 23,819,597 39,797,969
LinkedHashMap_Lru 10,179,891 10,859,549
Guava (default) 4,764,056 5,446,282
Guava (64) 8,128,024 7,483,986
Ehcache2_Lru 4,205,936 4,697,745
Ehcache3_Lru 10,051,020 13,939,317
Infinispan_Old_Lru 7,538,859 7,332,973
Infinispan_New_Lru 4,797,502 5,086,305

本地缓存推荐

Caffeine是在guava基础上进行优化的产物,也是带着替代guava的目的而来的,因而在使用上差别不大,但是通过测试可以明显看到Caffeine在性能上的优势。

Caffeine是Spring 5默认支持的Cache,可见Spring对它的看重。

Caffine是什么?

Caffeine是⼀个基于Java

8的⾼性能,接近最佳的缓存库。

Caffine有什么特⾊?

  • ⾃动将条⽬加载到缓存中,可选择异步加载
  •  基于频率和新近度超过最⼤值时的基于⼤⼩的驱逐
  •  ⾃上次访问或上次写⼊以来测量的条⽬的基于时间的到期
  •  当第⼀个条⽬的陈旧请求发⽣时,异步刷新
  •  密钥⾃动包含在弱引⽤中
  •  值⾃动包含在弱引⽤或软引⽤中
  •  被驱逐(或以其他⽅式删除)条⽬的通知
  •  写⼊传播到外部资源
  •  累积缓存访问统计信息

继续阅读