您的位置:首页 > 其它

Ehcache 缓存

2016-12-12 14:22 85 查看
为什么要有本地缓存?

在系统中,有些数据,数据量小,但是访问十分频繁,需要将数据搞到应用的本地缓存中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大),但是有一点需要注意,就是缓存的占用空间以及缓存的失效策略。

  在Ehcache中对于缓存的存储主要有三种方式:分别是堆内存、非堆内存和磁盘。其中非堆内存是针对于企业版Ehcache才有的功能,它可以不受Java GC的影响,能够创建很大的缓存。

(1)首先下载jar包 ehcache-core-2.3.0.jar

(2)编写ehcache.xml缓冲配置文件 可以放在src的任何目录下

1 堆内存(MemoryStore)   

    我们通常所有的MemoryStore实际上就是堆内存存储。MemoryStore总是可用的,所有的元素都可以储存在MemoryStore中。MemoryStore是线程安全的,相比另外两种储存方式而言其访问速度也是最快的。通常我们在往缓存里面添加元素的时候,其首先就是存放在MemoryStore里面的,但是我们又不能说连续不断的往MemoryStore里面存放元素,这就涉及到到底能放多少元素的问题。

1.1  指定可用内存

     Ehcache规定我们在使用一个Cache时必须在CacheManager级别指定可用的内存大小或者是在Cache级别指定可用的内存大小或所允许存放的元素的最大数量。在CacheManager级别指定的内存大小是其内部所有Cache一起所能使用的内存的最大量。CacheManager级别指定内存大小是通过maxBytesLocalHeap来指定的,如:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"

   maxBytesLocalHeap="500M">

 

</ehcache>

注:

1.上面指定了我们的CacheManager所能使用的最大内存是500M。

2.CacheManager级别指定了内存大小后我们在Cache上也可以指定其能使用的最大内存,但不能指定其所能存储元素的最大数量。

另外,如果我们的CacheManager没有指定可用的内存大小,我们可以通过maxBytesLocalHeap在Cache级别指定可用的内存大小,或者通过maxEntriesLocalHeap在Cache级别指定允许储存元素的最大数量,但是maxEntriesLocalHeap和maxBytesLocalHeap不能同时使用。如下在CacheManager级别使用maxBytesLocalHeap,然而在Cache级别使用maxEntriesLocalHeap是不行的。

1.2  驱除策略

      那么当我们内存中的元素大小或者数量超过了预设的大小之后怎么办呢?这个时候如果我们设置了允许溢出,如overflowToDisk或overflowToOffHeap,则会把某些元素溢出到对应的储存器中。如果不允许溢出,则会先删除原有的某些元素。至于是哪个元素溢出、哪个元素删除则在不存在超时的情况下与我们的内存驱除策略有关,

这是通过Cache的memoryStoreEvictionPolicy属性来指定的。其可选值有LRU、LFU和FIFO,默认是LRU。但是如果有过期元素存在的话则会优先驱除已经过期的元素,然后再考虑驱除策略memoryStoreEvictionPolicy。

       LRU(Least Recently Used):最近最少使用。当我们把一个元素储存到Cache中或者从Cache中取出时都会更新该元素的最后使用时间。当采用最近最少使用原则进行驱除时会优先把最后使用时间最早的元素进行驱除。

       LFU(Least Frequently Used):最不常使用的。每次我们从Cache中获取一个元素时都会更新该元素的hitCount属性值加1。当采用最不常使用原则进行驱除时hitCount属性值最小的元素将优先驱除。

       FIFO(First In First Out):先进先出。当采用这种驱除原则时将优先驱除最先储存的元素。

             

1.3  元素过期

    在上文中我们已经知道在不存在元素过期的情况下,驱除哪个元素是与我们的内存驱除策略有关的。但如果存在过期元素的话则会优先驱除已经过期的元素。关于控制元素是否过期我们可以通过cache的几个属性来定义。

    timeToIdleSeconds:单位是秒,表示一个元素在不被请求的情况下允许在缓存中存在的最长时间。默认值是0,表示不限制。

    timeToLiveSeconds:单位是秒,表示一个元素不管有没有被使用,其在缓存中允许存在的最长时间。默认是0,表示不限制。一般timeToLiveSeconds要比timeToIdleSeconds长,否则就timeToIdleSeconds就失去意义了。

    eternal:boolean类型,表示是否永恒,默认为false。当设为true时,表示缓存中的元素永远不会过期,timeToIdleSeconds和timeToLiveSeconds就失去作用了。这个时候元素就只能由驱除策略来进行驱除了。

       

    当我们的元素过期以后,为了保持Cache的性能,Ehcache不一定马上就会将过期的元素删除或者驱除到其它存储容器中,它可能还在原来的位置。之所以说不一定是因为有可能当一个元素过期时恰好Cache需要删除元素或者驱除元素到其它存储容器中,这个时候我们的过期元素将优先被删除或者驱除。另外,当我们在请求一个元素的时候,如果Ehcache发现该元素已经过期的话也会立刻将该元素删除。

   <cache name="ttt" maxBytesLocalHeap="50M" timeToIdleSeconds="600"  

       timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU" /> 

2 非堆内存(BigMemory)

   非堆内存存储是针对于企业版才有的功能,它可以不受Java GC的影响,能够创建很大的缓存。BigMemory保存的都是一个个的字节,在保存元素的时候Ehcache会对元素进行序列化再保存到BigMemory中,然后在读取的时候又会把读取到的字节进行反序列化。所以存放在其中的元素的key和value都必须是能够序列化的。

      

3 磁盘(DiskStore)

      磁盘存储可以存储内存中驱除过来的元素,也可以在系统重启的时候将内存中的缓存信息保存起来,供系统重新启动后使用。磁盘存储是非必须的,但是使用DiskStore的时候我们需要指定一个磁盘目录来存放缓存信息。这可以在ehcache.xml文件中的ehcahce元素下的定义一个diskStore元素并指定其path属性。由diskStore元素是定义在ehcache元素下我们看出diskStore在CacheManager范围内是共享的,其是线程安全的。如果我们没有定义diskStore元素时,DiskStore会使用默认的目录作为其存储目录,该目录就是java.io.tmpdir,即Java的临时目录。当然我们也可以指定一个绝对路径。

当我们指定diskStore元素的path为以下值时会被替换为实际对应的目录:

l  user.home:用户的家目录。

l  user.dir:用户的当前工作目录。

l  java.io.tmpdir:Java临时目录。

l  在命令行指定的属性,如“java -Dehcache.disk.store.dir=D:\\abc …..”。

       子目录的话可以这样指定:user.home/ehcache。

       此外需要注意的是因为DiskStore是把信息存放在磁盘上的,所以我们存放在磁盘上的元素必须是可以序列化的。CacheManager的DiskStore路径一旦设置好了之后将不能再更改。如果硬是更改了,那么我们的CacheManager需要基于新的路径重新建立。

3.1 指定可用容量

    指定可用容量的时候我们可以在CacheManager级别通过maxBytesLocalDisk来指定。而在Cache级别我们可以通过maxBytesLocalDisk和maxEntriesLocalDisk来指定。因为DiskStore是可选的,所以这些属性也都是可选的。另外不像MemoryStore那样,我们在Cache级别上可以同时指定maxBytesLocalDisk和maxEntriesLocalDisk。如:

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">  

      

        <diskStore path="java.io.tmpdir"/>  

      

        <!--  

        Mandatory Default Cache configuration. These settings will be applied to caches  

        created programmtically using CacheManager.add(String cacheName)  

        -->  

        <!--  

           name:缓存名称。  

           maxElementsInMemory:缓存最大个数。  

           eternal:对象是否永久有效,一但设置了,timeout将不起作用。  

           timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。  

           timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。  

           overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。  

           diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。  

           maxElementsOnDisk:硬盘最大缓存个数。  

           diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.  

           diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。  

           memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。  

           clearOnFlush:内存数量最大时是否清除。  

        -->  

        <defaultCache  

                maxElementsInMemory="10000"  

                eternal="false"  

                timeToIdleSeconds="120"  

                timeToLiveSeconds="120"  

                overflowToDisk="true"  

                maxElementsOnDisk="10000000"  

                diskPersistent="false"  

                diskExpiryThreadIntervalSeconds="120"  

                memoryStoreEvictionPolicy="LRU"  

                />        

        <cache name="authCache1"  

           maxElementsInMemory="36"  

           maxElementsOnDisk="10000"  

           eternal="true"  

           diskPersistent="true"  

           overflowToDisk="true"  

           diskSpoolBufferSizeMB="20"  

           timeToIdleSeconds="300"  

           timeToLiveSeconds="600"  

           memoryStoreEvictionPolicy="LRU"  

            /> 

    </ehcache> 

4 Cache 配置文件的加载方式

(1) 无参

CacheManager manager = new CacheManager();

(2) 通过配置文件

CacheManager manager = new CacheManager("src/config/ehcache.xml");

(3) 通过资源

URL url = getClass().getResource("/anotherconfigurationname.xml");

CacheManager manager = new CacheManager(url);

(4) 通过输入流

InputStream fis = new FileInputStream(new File("src/config/ehcache.xml").getAbsolutePath());

try {

             CacheManager manager = new CacheManager(fis);

} finally {

           fis.close();

}

5 增加或删除 Cache

   
(一)增加 Cache 有两种方式:

       (1) 使用 CacheManager 的 addCache(String)

         CacheManager singletonManager = CacheManager.create();

         singletonManager.addCache("testCache");

         Cache test = singletonManager.getCache("testCache");

       (2) 新增一个 Cache ,然后加到 CacheManager 中, Cache 在加入 CacheManager 之前是不能使用的

           CacheManager singletonManager = CacheManager.create();

           Cache memoryOnlyCache = new Cache("testCache", 5000, false, false, 5, 2);

           manager.addCache(memoryOnlyCache);

           Cache test = singletonManager.getCache("testCache");

   (二)从 CachaManager 中删除 Cache

        CacheManager singletonManager = CacheManager.create();

        singletonManager.removeCache("sampleCache1");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: