ehcache3.3官方文档地址
我用的是springBoot和Ehcache3.3
1.在maven的pom.xml导入ehcache3.3.0依赖
org.ehcache
ehcache
3.3.0
一、无xml版本配置
1.创建一个EhcacheUtil.java类用来保存配置
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import java.io.FileNotFoundException;
import java.util.concurrent.TimeUnit;
/**
* ClassName: EhcacheConfig
* Description: Ehcache配置
* Author: [email protected]
* Date: 2018/05/18 14:30:36
*/
@Configuration
@EnableCaching
public class EhcacheUtil {
private static CacheManager cacheManager;
/**
* 初始化Ehcache缓存对象
*/
public EhcacheUtil() {
System.out.println("[Ehcache配置初始化<开始>]");
// 配置默认缓存属性
CacheConfiguration cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(
// 缓存数据K和V的数值类型
// 在ehcache3.3中必须指定缓存键值类型,如果使用中类型与配置的不同,会报类转换异常
String.class, String.class,
ResourcePoolsBuilder
.newResourcePoolsBuilder()
//设置缓存堆容纳元素个数(JVM内存空间)超出个数后会存到offheap中
.heap(1000L,EntryUnit.ENTRIES)
//设置堆外储存大小(内存存储) 超出offheap的大小会淘汰规则被淘汰
.offheap(100L, MemoryUnit.MB)
// 配置磁盘持久化储存(硬盘存储)用来持久化到磁盘,这里设置为false不启用
.disk(500L, MemoryUnit.MB, false)
).withExpiry(Expirations.timeToLiveExpiration(
//设置缓存过期时间
Duration.of(30L, TimeUnit.SECONDS))
).withExpiry(Expirations.timeToIdleExpiration(
//设置被访问后过期时间(同时设置和TTL和TTI之后会被覆盖,这里TTI生效,之前版本xml配置后是两个配置了都会生效)
Duration.of(60L, TimeUnit.SECONDS))
)
// 缓存淘汰策略 默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
// 这块还没看
/*.withEvictionAdvisor(
new OddKeysEvictionAdvisor())*/
).build();
// CacheManager管理缓存
cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
// 硬盘持久化地址
.with(CacheManagerBuilder.persistence("D:/ehcacheData"))
// 设置一个默认缓存配置
.withCache("defaultCache", cacheConfiguration)
//创建之后立即初始化
.build(true);
System.out.println("[Ehcache配置初始化<完成>]");
}
}
2.在main方法中进行测试
1)测试heap配置
修改配置
//设置缓存堆容纳元素个数(JVM内存空间)
.heap(1L, EntryUnit.ENTRIES)
//设置堆外储存大小(内存存储)
//.offheap(100L, MemoryUnit.MB)
// 配置磁盘持久化储存(硬盘存储)
//.disk(500L, MemoryUnit.MB, false)
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
// 初始化Ehcache对象
new EhcacheUtil();
// 获取初始化的缓存对象
Cache mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
// 创建测试内容
StringBuilder strTemp = new StringBuilder("测试");
// 存入第1条数据
mineCache.put("key", strTemp.toString());
// 取出并输出
System.out.println("key:" + mineCache.get("key"));
strTemp = new StringBuilder("测试2");
// 存入第2条数据
mineCache.put("key2", strTemp.toString());
// 取出并输出
System.out.println("key2:" + mineCache.get("key2"));
// 取出并输出第一条数据,因为heap的个数设置为1所以当存入第2条数据时,第一条会被淘汰
System.out.println("key1:" + mineCache.get("key1"));
// 关闭ehcache
cacheManager.close();
}
//控制台输出的结果
Connected to the target VM, address: '127.0.0.1:61909', transport: 'socket'
[Ehcache配置初始化<开始>]
13:41:55.435 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - Starting 17 Services...
13:41:55.465 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - RootDirectory Locked
13:41:55.475 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully started, 17 Services in 40ms
13:41:55.485 [main] DEBUG org.ehcache.core.EhcacheManager - Creating Cache 'defaultCache' in EhcacheManager.
13:41:55.485 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for : org.ehcache.impl.serialization.StringSerializer@52e677af
13:41:55.485 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for : org.ehcache.impl.serialization.StringSerializer@7d68ef40
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for : org.ehcache.impl.copy.IdentityCopier@475e586c
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for : org.ehcache.impl.copy.IdentityCopier@657c8ad9
13:41:55.685 [main] DEBUG class org.ehcache.core.Ehcache-defaultCache - Initialize successful.
13:41:55.685 [main] INFO org.ehcache.core.EhcacheManager - Cache 'defaultCache' created in EhcacheManager.
13:41:55.685 [main] DEBUG org.ehcache.core.EhcacheManager - Initialize successful.
[Ehcache配置初始化<完成>]
key:测试
key2:测试2
key1:null
Disconnected from the target VM, address: '127.0.0.1:61909', transport: 'socket'
13:41:55.695 [main] DEBUG class org.ehcache.core.Ehcache-defaultCache - Close successful.
13:41:55.695 [main] INFO org.ehcache.core.EhcacheManager - Cache 'defaultCache' removed from EhcacheManager.
13:41:55.695 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - Stopping 17 Services...
13:41:55.695 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - RootDirectory Unlocked
13:41:55.695 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully stopped, 17 Services in 0ms
13:41:55.695 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.
Process finished with exit code 0
2)测试heap和offheap
设置heap个数为1,offheap大小为1MB(offheap最小为1MB)
// 测试heap容纳个数和offheap,将配置中其它无关配置注释掉
// 设置缓存堆容纳元素个数(JVM内存空间)
.heap(1L, EntryUnit.ENTRIES)
// 设置堆外储存大小(内存存储)
.offheap(1L, MemoryUnit.MB)
// 配置磁盘持久化储存(硬盘存储)
//.disk(500L, MemoryUnit.MB, false)
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
// 初始化Ehcache对象
new EhcacheUtil();
// 获取初始化的缓存对象
Cache mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
// 创建测试内容
StringBuilder strTemp = new StringBuilder("测试");
strTemp.append("测试一二三四五六七八九十");
System.out.println("大小为:" + strTemp.toString().getBytes() + "Byte");
// 存入第1条数据
mineCache.put("key", strTemp.toString());
// 取出并输出
System.out.println("key:" + mineCache.get("key"));
strTemp = new StringBuilder("测试2");
// 存入第2条数据
mineCache.put("key2", strTemp.toString());
// 取出并输出
System.out.println("key2:" + mineCache.get("key2"));
// 取出并输出第一条数据,由于offheap的个存在所以当存入第2条数据时,第一条会被存储到offheap中而不会被淘汰
System.out.println("key:" + mineCache.get("key"));
// 关闭ehcache
cacheManager.close();
}
由于控制台日志太多下面只截取部分有用日志
[Ehcache配置初始化<开始>]
[Ehcache配置初始化<完成>]
key:测试测试一二三四五六七八九十
key2:测试2
key:测试测试一二三四五六七八九十
14:01:41.686 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.
Process finished with exit code 0
设置第一条记录的大小大于offheap 的大小
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
// 初始化Ehcache对象
new EhcacheUtil();
// 获取初始化的缓存对象
Cache mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
// 创建测试内容
StringBuilder strTemp = new StringBuilder("测试");
while(strTemp.toString().getBytes().length <= 1024*1024){
strTemp.append("测试一二三四五六七八九十");
}
System.out.println("大小为:" + strTemp.toString().getBytes().length + " Byte,1MB大小为:" + 1024*1024 + " Byte");
// 存入第1条数据
mineCache.put("key", strTemp.toString());
// 取出并输出
System.out.println("key:" + mineCache.get("key"));
strTemp = new StringBuilder("测试2");
// 存入第2条数据
mineCache.put("key2", strTemp.toString());
// 取出并输出
System.out.println("key2:" + mineCache.get("key2"));
// 取出并输出第一条数据,由于offheap的个存在所以当存入第2条数据时,第一条会被存储到offheap中,但是第一条数据的大小大于offheap所以会被淘汰
System.out.println("key:" + mineCache.get("key"));
// 关闭ehcache
cacheManager.close();
}
[Ehcache配置初始化<开始>]
[Ehcache配置初始化<完成>]
大小为:1048578 Byte,1MB大小为:1048576 Byte
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 1020.0KB to 1022.0KB [occupation=0.0]
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Allocating a 2KB buffer from chunk 0 &2048
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 1022.0KB to 1MB [occupation=0.0]
14:06:50.967 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expansion from 1046528 failed
14:06:50.977 [main] INFO org.ehcache.core.internal.resilience.LoggingRobustResilienceStrategy - Ehcache key key recovered from
org.ehcache.core.spi.store.StoreAccessException: The element with key 'key' is too large to be stored in this offheap store.
at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.computeWithRetry(AbstractOffHeapStore.java:1101)
at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.put(AbstractOffHeapStore.java:316)
at org.ehcache.impl.internal.store.tiering.TieredStore.put(TieredStore.java:138)
at org.ehcache.core.Ehcache.put(Ehcache.java:198)
at com.linewell.egov.config.EhcacheUtil.main(EhcacheUtil.java:157)
Caused by: org.terracotta.offheapstore.exceptions.OversizeMappingException: Storage Engine and Eviction Failed - Empty Map
Storage Engine : OffHeapBufferStorageEngine allocated=1022.0KB occupied=0B
Storage Area: OffHeapStorageArea
511 2KB pages
Allocator: org.terracotta.offheapstore.storage.allocator.IntegerBestFitAllocator@229c6181
Page Source: UpfrontAllocatingPageSource
Chunk 1
Size : 1MB
Free Allocator : PowerOfTwoAllocator: Occupied 1022.5KB [Largest Available Area 1KB]
Victim Allocator : PowerOfTwoAllocator: Occupied 512B [Largest Available Area 512KB]
at org.terracotta.offheapstore.AbstractOffHeapClockCache.storageEngineFailure(AbstractOffHeapClockCache.java:84)
at org.terracotta.offheapstore.OffHeapHashMap.writeEntry(OffHeapHashMap.java:689)
at org.terracotta.offheapstore.OffHeapHashMap.computeWithMetadata(OffHeapHashMap.java:1947)
at org.terracotta.offheapstore.AbstractLockedOffHeapHashMap.computeWithMetadata(AbstractLockedOffHeapHashMap.java:582)
at org.terracotta.offheapstore.concurrent.AbstractConcurrentOffHeapMap.computeWithMetadata(AbstractConcurrentOffHeapMap.java:743)
at org.ehcache.impl.internal.store.offheap.EhcacheConcurrentOffHeapClockCache.compute(EhcacheConcurrentOffHeapClockCache.java:152)
at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.computeWithRetry(AbstractOffHeapStore.java:1099)
... 4 common frames omitted
key:null
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Freeing a 2KB buffer from chunk 0 &2048
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Allocating a 2KB buffer from chunk 0 &1046528
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 2KB to 4KB [occupation=0.0]
key2:测试2
key:null
Disconnected from the target VM, address: '127.0.0.1:63287', transport: 'socket'
14:06:56.191 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully stopped, 17 Services in 10ms
14:06:56.191 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.
Process finished with exit code 0
关于TTL和TTI的测试这里就不贴代码了得出结论是TTL和TTI同时配置时,二者不可共存后面的配置会覆盖前面的,XML配置同理
二、xml版本配置
在resource文件夹下创建ehcache.xml文件
java.lang.String
java.lang.String
1
1
1
20
60
500
public EhcacheUtil() {
System.out.println("[Ehcache配置初始化<开始>]");
// 配置默认缓存属性
cacheManager = CacheManagerBuilder.newCacheManager(new XmlConfiguration(getClass().getResource("/ehcache.xml")));
cacheManager.init();
System.out.println("[Ehcache配置初始化<完成>]");
}
应该也可以这样配置到application.yml中,可自行尝试
spring:
cache:
ehcache:
config: ehcache.xml
// ehcache3.5.2中缓存过期策略有所更新旧的方法参数已经过期新参数设置可以参考下面
// 过期策略设置为不过期
.withExpiry(ExpiryPolicy.NO_EXPIRY)
如需转载求标明出处, https://blog.csdn.net/Gentlemike/article/details/80403967