一、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();
}
}
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情