一、EhCache配置
EhCache提供很多丰富的配置,其中有两个是很重要的。
1.1 数据存储位置
EhCache3.x版本中不但提供了堆内缓存heap,还提供了堆外缓存off-heap,并且还提供了数据的持久化操作,可以将数据落到磁盘中disk。
heap堆内内存存储
heap表示使用堆内内存:
- heap(10)代表当前Cache最多只能存储10个数据,当你put第11个数据时,第一个数据就会被移除。
- heap(10,大小单位MB)代表当前Cache最多只能存储10MB数据。
off-heap堆外内存
off-heap是将存储的数据放到操作系统的一块内存区域存储,不是JVM内部,这块空间属于RAM。这种对象是不能直接拿到JVM中使用的,在存储时,需要对数据进行序列化操作,同时获取出来的时候也要做反序列化操作。
disk落到磁盘
disk表将数据落到本地磁盘,这样的话,当服务重启后,依然会从磁盘反序列化数据到内存中。
EhCache提供了三种
组合方式:
- heap + off-heap
- heap + disk
- heap + off-heap + disk
在组合情况下存储,存储数据时,数据先落到堆内内存,同时同步到对外内存以及本地磁盘。本地底盘因为空间充裕,所以本地磁盘数据是最全的。而且EhCache要求空间大小必须disk > off-heap > heap。
在组合情况下读取,因为性能原型,肯定是先找heap查询数据,没有数据去off-heap查询数据,off-heap没有数据再去disk中读取数据,同时读取数据之后,可以将数据一次同步到off-heap、heap
通过API实现组合存储方式:
@Test public void test(){ //0. 声明存储位置 String path = "D:\\ehcache"; //1. 初始化好CacheManager CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() // 设置disk存储的位置 .with(CacheManagerBuilder.persistence(path)) .withCache( "singleDog", CacheConfigurationBuilder.newCacheConfigurationBuilder( String.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(10) // 堆外内存 .offheap(10, MemoryUnit.MB) // 磁盘存储,记得添加true,才能正常的持久化,并且序列化以及反序列化 .disk(11,MemoryUnit.MB, true) .build() ).build() ).build(true); //2. 基于CacheManager回去到Cache对象 Cache<String, String> cache = cacheManager.getCache("singleDog", String.class, String.class); //3. 存 // cache.put("singleDog","29个单身狗!!"); //4. 取 System.out.println(cache.get("singleDog")); //5. 保证数据正常持久化不丢失,记得cacheManager.close(); cacheManager.close(); } 复制代码
本地磁盘存储的方式,一共有三个文件
- mata:元数据存储,记录这当前cache的key类型和value类型
- data:存储具体数据的位置,将数据序列化成字节存储
- index:类似索引,帮助查看数据的。
1.2 数据生存时间
因为数据如果一致存放在内存当中,可能会出现内存泄漏等问题,数据在内存,一致不用,还占着空间
EhCache提供了对数据设置生存时间的机制
提供了三种机制:
- noExpiration:不设置生存时间
- timeToLiveExpiration:从数据落到缓存计算生存时间
- timeToIdleExpiration:从最后一个get计算生存时间
@Test public void test() throws InterruptedException { //1. 初始化好CacheManager CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withCache( "singleDog", CacheConfigurationBuilder.newCacheConfigurationBuilder( String.class, Object.class, ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10).build()) // 三选一。 // 不设置生存时间 // .withExpiry(ExpiryPolicy.NO_EXPIRY) // 设置生存时间,从存储开始计算 // .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMillis(1000))) // 设置生存时间,每次获取数据后,重置生存时间 .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofMillis(1000))) .build() ).build(true); Cache<String, Object> cache = cacheManager.getCache("singleDog", String.class, Object.class); cache.put("ehcache","24个单身狗!!"); System.out.println(cache.get("ehcache")); Thread.sleep(500); cache.get("ehcache"); Thread.sleep(500); System.out.println(cache.get("ehcache")); } 复制代码
二、SpringBoot整合EhCache
SpringBoot默认情况下是整合了EhCache的,但是SPringBoot整合的EhCache的2.x版本。
这里依然整合EhCache的3.x版本。
2.1 构建SpringBoot工程
阿巴阿巴
2.2 导入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.8.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> </dependencies> 复制代码
2.3 准备EhCache的配置项
# 准备EhCache基础配置项 ehcache: heap: 1000 # 堆内内存缓存个数 off-heap: 10 # 对外内存存储大小 MB disk: 20 # 磁盘存储数据大小 MB diskDir: D:/data/ # 磁盘存储路径 cacheNames: # 基于CacheManager构建多少个缓存 - user - item - card 复制代码
引入配置文件中的配置项
@Component @ConfigurationProperties(prefix = "ehcache") public class EhCacheProps { private int heap; private int offheap; private int disk; private String diskDir; private Set<String> cacheNames; } 复制代码
2.4 配置CachaManager
@Configuration @EnableCaching public class EhCacheConfig { @Autowired private EhCacheProps ehCacheProps; @Bean public CacheManager ehCacheManager(){ //1. 缓存名称 Set<String> cacheNames = ehCacheProps.getCacheNames(); //2. 设置内存存储位置和数量大小 ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(ehCacheProps.getHeap()) .offheap(ehCacheProps.getOffheap(), MemoryUnit.MB) .disk(ehCacheProps.getDisk(),MemoryUnit.MB) .build(); //3. 设置生存时间 ExpiryPolicy expiry = ExpiryPolicyBuilder.noExpiration(); //4. 设置CacheConfiguration // baseObject是一个POJO类实现了序列化接口 CacheConfiguration cacheConfiguration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, BaseObject.class, resourcePools) .withExpiry(expiry) .build(); //5. 设置磁盘存储的位置 CacheManagerBuilder<PersistentCacheManager> cacheManagerBuilder = CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(ehCacheProps.getDiskDir())); //6. 缓存名称设置好。 for (String cacheName : cacheNames) { cacheManagerBuilder.withCache(cacheName,cacheConfiguration); } //7. 构建 return cacheManagerBuilder.build(); } }