EhCache-配置和SpringBoot整合

2,155 阅读4分钟

一、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

image.png

在组合情况下存储,存储数据时,数据先落到堆内内存,同时同步到对外内存以及本地磁盘。本地底盘因为空间充裕,所以本地磁盘数据是最全的。而且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天,点击查看活动详情