关于Ehcache持久化缓存的一些见解

发布于:2023-01-04 ⋅ 阅读:(430) ⋅ 点赞:(0)

1.前言

今天在学习Ehcache相关的知识,前面写配置文件以及简单测试类的时候还是一帆风顺的~

直到我碰到Ehcache的磁盘持久化机制

2.相关配置

我依赖的jar包版本是下面这个

<dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.10.2</version>
</dependency>

参照网上的资料编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

  <!-- 磁盘缓存位置 -->
  <diskStore path="java.io.tmpdir/ehcache"/>

  <!-- 默认缓存 -->
  <defaultCache
          maxEntriesLocalHeap="10000"
          eternal="false"
          timeToIdleSeconds="120"
          timeToLiveSeconds="120"
          maxEntriesLocalDisk="10000000"
          diskExpiryThreadIntervalSeconds="120"
          memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
  </defaultCache>

  <!-- helloworld缓存 -->
  <cache name="HelloWorldCache"
         maxElementsInMemory="1000"
         eternal="false"
         timeToIdleSeconds="50000"
         timeToLiveSeconds="50000"
         overflowToDisk="false"
         memoryStoreEvictionPolicy="LRU"/>
</ehcache>

下面就说下我遇到的几个“坑”

3.overflowToDisk

首先是overflowToDisk这个属性,这个属性我一开始的理解是设置为true后,当内存中缓存的对象大于maxElementsInMemory的数值,他就会自动将我们在内存中缓存的对象序列化到我配置的磁盘路径(缓存的对象已经实现序列化接口)。

但其实不然,描述下我测试这个过程的整个步骤

一、我编写了一个测试类如下

    @Test
    public void test() throws IOException {
        //绑定资源路径
        CacheManager cacheManager=CacheManager.create(Resources.getResourceAsStream("ehcache.xml"));

        //获取cache
        Cache cache = cacheManager.getCache("HelloWorldCache");

        Person person = new Person("a",1);
        Person person2 = new Person("b",2);
        Person person3 = new Person("c",3);

        //新建两个Element对象
        Element element = new Element("person", person);
        Element element2 = new Element("person2", person2);
        Element element3 = new Element("person3", person2);

        //将元素添加到缓存
        cache.put(element);
        cache.put(element2);
        cache.put(element3);

        System.out.println(cache.get("person"));
        System.out.println(cache.get("person2"));
        System.out.println(cache.get("person3"));

        System.out.println(cache.getSize());

        cacheManager.shutdown();
    }

 

 二、为了验证ehcache的磁盘序列化,我先尝试将maxElementsInMemory的数值等于1,然后再运行上述的代码,得到的结果是

 这个结果也在预料之中,按照配置的清除策略,最先被创建的对象会被清除,然后我尝试将overflowToDisk修改为true,我的认为的结果是ehcache会将超出的对象序列化到我配置的磁盘路径,但结果不然

三个对象的确都打印出来了,但是我在配置文件所配置的磁盘路径下的文件夹却是空空如也~

 难道ehcache欺骗了我!但是我也在控制台输出了和之前不一样的结果,说明这个属性的配置的确改变了什么

三、在思考过后我决定前往默认的磁盘缓存目录下一探究竟,终于让我发现,确实某些文件被创建了出来

 具体原理以及过程我不是很确定,以我自己的理解:我觉得ehcache的确将超出的对象进行了序列化,并且放在了上述的目录中

4.diskPersistent

该属性是用于在JVM重启时将加载在硬盘的缓存数据,本来是个非常容易懂得概念,但是在实操的时候我发现了一些“状况”

一、在配置该属性为true后,我马上重新启动我的测试类,但不一样的是,我将三行代码注释了

因为我认为ehcache已经帮我把这些数据序列化到磁盘上了,所以我认为是可以直接得到这三个对象的,但结果不然 ,我得到了三个空指针

二、于是我又将三行注释打开,再执行了一遍程序

 

这次在我配置的磁盘目录下出现了数据,然后当我再次将上面三行代码注释重新执行程序

终于得到了我如愿以偿的结果 

5.总结

  • 没有配置overflowToDisk属性前,达到最大缓存对象数目(即maxElementsInMemory后),ehcache会根据策略清理缓存,但是配置overflowToDisk属性后,缓存会得到保留,个人认为他是将缓存保存到磁盘上(但不是自己配置的目录,而是他的一个默认目录)
  • 想要将缓存持久化到磁盘,并且关闭服务器后下次打开可以继续使用上次的缓存,则必须要配置diskPersistent属性为true,才会将数据持久化到你配置的路径文件夹中(甚至不需要配置overflowToDisk)
  • 缓存要想持久化,一定要执行cacheManager.shutdown()这条语句,否则强行中断程序或者不写(只写flush也不行)都是没办法序列化数据的(建议配置个监听器)
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到