Ehcache(04)——设置缓存的大小

系统 1896 0

设置缓存的大小

 

目录

1     CacheManager 级别

2     Cache 级别

3     大小衡量

4     配置大小示例

 

       缓存大小的限制可以设置在 CacheManager 上,也可以设置在单个的 Cache 上。我们可以设置缓存使用内存的大小,也可以设置缓存使用磁盘的大小,但是使用堆内存的大小是必须设置的,其它可设可不设,默认不设就是无限制。在设置缓存大小的时候,我们可以设置缓存使用某一个存储器的最大字节数,也可以设置缓存在某一个存储器上最多存放元素的数量。

 

1        CacheManager 级别

       CacheManager 级别有三个属性可以分别用来限制三种存储器缓存信息的大小,其控制的都是字节数,分别是 maxBytesLocalHeap maxBytesLocalOffHeap maxBytesLocalDisk CacheManager 级别限制的大小是其内所有的 Cache 共享的。

       maxBytesLocalHeap 是用来限制缓存所能使用的堆内存的最大字节数的,其单位可以是 K M G ,不区分大小写。默认是 0 ,表示不限制。但是当我们没有指定 CacheManager 级别的 maxBytesLocalHeap 时,我们必须在每一个 Cache 上指定 maxBytesLocalHeap maxEntriesLocalHeap

       maxBytesLocalOffHeap 是用来限制缓存所能使用的非堆内存的最大字节数,其单位也可以是 K M G 。默认是 0 ,表示不限制。但是 当我们在 CacheManager 级别指定了 maxBytesLocalOffHeap 时就会隐式的使所有 Cache 级别的 overflowToOffHeap true ,在 Cache 级别使用该属性时只会使当前 Cache overflowToOffHeap true 如果此时不需要 overflowToOffHeap 的话,那么我们需要在 Cache 级别显示的指定 overflowToOffHeap false 。只有企业版的 Ehcache 才能使用非堆内存存储缓存信息。

       maxBytesLocalDisk 是用来限制缓存所能使用的磁盘的最大字节数的,其单位可以是 K M G 。默认是 0 ,表示不限制。只有在单机环境下才可以使用本地磁盘,分布式环境下是不可以使用的。另外,这个设置只适用于临时将缓存内的信息写入到磁盘的情况,对于持久化缓存信息到磁盘的情况是不适用的。 Cache 级别的 maxBytesLocalDisk 同样如此。 当我们在 CacheManager 级别指定了 maxBytesLocalDisk 时会隐式的指定所有 Cache overflowToDisk true ,而 Cache 级别只会使当前 Cache overflowToDisk true

       下面是一个在 CacheManager 级别指定缓存大小限制的示例,在该示例中我们指定了该 CacheManager 所能使用的最大堆内存是 500M ,最大非堆内存是 2G ,使用本地磁盘的最大字节数是 50G

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
   maxBytesLocalHeap="500M" maxBytesLocalOffHeap="2G" maxBytesLocalDisk="50G">
 
</ehcache>
    

 

 

2        Cache 级别

       CacheManager 上能够指定的限制大小的参数在 Cache 级别都能使用。当我们在 Cache 级别指定了某种类型的限制大小后,该 Cache 将不再共享 CacheManager 内的该种限制了。如我们在 CacheManager 级别限制了堆内存的最大使用数 maxBytesLocalHeap 1G ,意味着 CacheManager 内的所有的 Cache 将共享这 1G 的堆内存,如果这个时候我们指定 CacheManager 内的 cache1 的最大使用堆内存数 maxBytesLocalHeap 200M ,那就意味着 cache1 的堆内存最大使用数只能是其自身设置的 200M 了,而其它 Cache 只能共享剩余的 824M 了。

       CacheManager 不同的是我们 Cache 级别上 指定 maxBytesLocalHeap maxBytesLocalOffHeap maxBytesLocalDisk 时还可以 使用百分比 的形式, 前提是对应的限制在 CacheManager 上有指定 。打个比方,我们的 CacheManager 有如下配置,我们指定了其最多使用的堆内存是 500M ,那么这个时候我们在其中定义了一个 Cache ,在指定其 maxBytesLocalHeap 时我们可以指定其值为百分比形式,如 50% ,表示我们的 Cache 最多使用 CacheManager 级别的 maxBytesLocalHeap 50% ,即 250M 。而如果我们试图在该 Cache 上使用百分比的时候指定 maxBytesLocalDisk 时则会出错,因为我们没有在 CacheManager 级别上指定 maxBytesLocalDisk Ehcache 也就无法知道你这个百分比到底是多少了。需要注意的是 我们所有 Cache 上指定的字节数大小之和不能超过 CacheManager 上对应的限制大小;所有 Cache 上对应限制以百分比形式指定的和不能超过 100%

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

 

      

       此外,在 Cache 级别我们还可以利用两个属性来限制在堆内存或者是磁盘上缓存元素的最大数,这两个属性是 maxEntriesLocalHeap maxEntriesLocalDisk ,而对于非堆内存 OffHeap 的话是不能指定元素的最大数量的。

       maxEntriesLocalHeap 是用来限制当前缓存在堆内存上所能保存的最大元素数量的。 Ehcache 规定如果在 CacheManager 上没有指定 maxBytesLocalHeap 时必须在各个 Cache 上指定 maxBytesLocalHeap 或者 maxEntriesLocalHeap ,但 maxEntriesLocalHeap maxBytesLocalHeap 不能同时出现。也就是说我们不能在一个 Cache 上同时指定 maxBytesLocalHeap maxEntriesLocalHeap ,当然我们也不能在 Cache 上指定 maxEntriesLocalHeap 的同时在 CacheManager 上指定 maxBytesLocalHeap 。但同时在 CacheManager Cache 上指定 maxBytesLocalHeap 则是允许的。

       maxEntriesLocalDisk 是用来限制在磁盘上所能保存的元素的最大数量的。( 暂时觉得这种保存的数量限制应该是对应于持久化的保存 )。

 

3        大小衡量

       放在 Cache 里面的元素将会使用 net.sf.ehcache.pool.sizeof.SizeOf 来衡量其大小,当然 这种衡量只是针对于存在堆内存里面的元素而言的,因为非堆内存和磁盘上我们是直接存的字节,可以直接来计算字节 。元素的大小包括元素的 key value ,以及其它属性信息,而且在计算大小时这些信息都是递归计算的,即如果 value 关联了另外一个对象 B ,那么 B 的大小也会被计算在内。如果我们不想计算元素内部某部分内容的大小的话,我们可以通过使用 net.sf.ehcache.pool.sizeof.annotations.IgnoreSizeOf 注解来标记忽略该内容的大小。 IgnoreSizeOf 是不会考虑继承性的,也就是说如果你将 IgnoreSizeOf 标注在类型 A 上,那么将只会忽略 A 的大小,而不会忽略 A 的子类 B 的大小,如果也需要忽略 B 的大小的话,则需要在类 B 上也使用 IgnoreSizeOf 进行标注。

       IgnoreSizeOf 可以标记在三个地方。

       1 属性上 :表示忽略某对象的对应属性。如下表示我们将忽略 User 对象的 role 属性。

      public class User {
 
   @IgnoreSizeOf
   private Role role;
  
}
    

 

 

       2 类上 :表示将忽略该中类型。如下表示我们将忽略 User 类型。

      @IgnoreSizeOf
public class User {
 
   private String name;
  
}
    

 

 

       3 包上 :标记在包上的时候是标记在包对应的 package-info.java 上,表示将忽略该包下面所有的类型,如我们要忽略 com.xxx.xxx 包下的所有内容时可以在该包对应的 package-info.java 文件中的 package 上使用 IgnoreSizeOf 注解进行标注。

      @net.sf.ehcache.pool.sizeof.annotations.IgnoreSizeOf
package com.xxx.xxx;
    

 

 

       此外,我们也可以通过全限定名的方式指定在计算 Cache 中元素的大小时哪些属性、类和包需要忽略,然后把这些信息写在一个属性文件里面,再将系统属性 net.sf.ehcache.sizeof.filter 指向该文件。系统属性可以通过 java –Dnet.sf.ehcache.sizeof.filter 来指定。


Ehcache(04)——设置缓存的大小
 

 

       如上所述,我们的 SizeOf 在进行大小衡量的时候是进行递归衡量的,即会计算对象所持有的引用、引用的引用等。针对于此,我们可以来指定 SizeOf 在进行大小衡量时的一个策略, sizeOfPolicy sizeOfPolicy CacheManager 级别的和 Cache 级别的,分别对应于 ehcache 子元素和 cache 子元素或 defaultCache 子元素。当 Cache 级别和 CacheManager 级别同时指定有 sizeOfPolicy 时, Cache 级别的配置将覆盖 CacheManager 级别的配置。 sizeOfPolicy 元素有两个属性, maxDepth maxDepthExceededBehavior

l   maxDepth 表示链接的最大深度。

l   maxDepthExceededBehavior 表示当访问的深度超过指定的 maxDepth 后的行为,对应有 continue abort 两种。 continue 将给出一个警告,然后继续计算大小,这是默认值; abort 将给出警告,然后中止此次计算,并标记没有跟踪到内存的使用。

 

4        配置大小示例

 

1 )只在 CacheManager 级别指定大小限制,没有在 Cache 级别指定,这种情况下 cache1 cache2 cache3 将平分 CacheManager 级别的大小限制,即各自拥有 CacheManager 级别的 heap offHeap disk 三分之一的容量。

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
   maxBytesLocalHeap="500M" maxBytesLocalOffHeap="5G" maxBytesLocalDisk="50G">
  
   <cache name="cache1"/>
   <cache name="cache2"/>
   <cache name="cache3"/>
 
</ehcache>
    

 

 

2 CacheManager 级别指定了大小限制,同时某些 Cache 也指定了大小限制。如下,我们指定了 cache1 maxBytesLocalHeap 200M ,这个时候 cache1 将可以使用到 200M 的堆内存,而 cache2 cache3 将平分 CacheManager 级别除去 cache1 所拥有的 200M 之外的堆内存,即各 150M 。而 CacheManager 级别的 offHeap disk 容量将由 cache1 cache2 cache3 平分,各得三分之一。

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
   maxBytesLocalHeap="500M" maxBytesLocalOffHeap="5G" maxBytesLocalDisk="50G">
  
   <cache name="cache1" maxBytesLocalHeap="200M"/>
   <cache name="cache2"/>
   <cache name="cache3"/>
 
</ehcache>
    

 

 

3 CacheManager 不指定大小限制, Cache 级别指定大小限制。这个时候将各用各的,即各个 Cache 只能使用其自身指定好的大小。

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
  
   <cache name="cache1" maxBytesLocalHeap="200M"/>
   <cache name="cache2" maxBytesLocalHeap="300M"/>
   <cache name="cache3" maxBytesLocalHeap="200M"/>
 
</ehcache>
    

 

 

4 )当我们在 CacheManager 级别指定了大小限制之后,我们可以在 Cache 级别通过百分比的形式来指定其可使用的对应大小限制。在下面示例中,我们的 CacheManager 拥有 500M heap 内存, 5G offHeap 内存, 50G disk 容量。 cache1 拥有 CacheManager 20% heap 内存,即 100M ,剩余的 400M cache2 cache3 平分,即各 200M cache2 拥有 CacheManager 20% offHeap 内存,即 1G ,剩余的 4G 将由 cache1 cache3 平分,即各 2G cache3 拥有 CacheManager 20% disk 容量,即 10G ,剩余的 40G 将由 cache1 cache2 平分,即各 20G 。所以最终 cache1 将拥有 heap 100M offHeap 2G disk 20G cache2 将拥有 heap 200M offHeap 1G disk 20G cache3 将拥有 heap 200M offHeap 2G disk 10G

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
   maxBytesLocalHeap="500M" maxBytesLocalOffHeap="5G" maxBytesLocalDisk="50G">
  
   <cache name="cache1" maxBytesLocalHeap="20%"/>
   <cache name="cache2" maxBytesLocalOffHeap="20%"/>
   <cache name="cache3" maxBytesLocalDisk="20%"/>
 
</ehcache>
    

 

 

5 )当我们没有在 CacheManager 上指定某种资源的可用量时我们还可以在 Cache 级别进行指定。 CacheManager 只有 600M heap 内存, cache1 cache2 cache3 都没有显式的指定使用多少 heap 内存,所以将各得 200M heap 内存。而 cache1 还指定了可以使用 2G offHeap 内存; cache2 还指定了可以使用 20G 的磁盘;而 cache3 仅仅只能使用 CacheManager 分配下来的 200M heap 内存。

      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
   maxBytesLocalHeap="600M">
  
   <cache name="cache1" maxBytesLocalOffHeap="2G"/>
   <cache name="cache2" maxBytesLocalDisk="20G"/>
   <cache name="cache3"/>
 
</ehcache>
    

 

 

       总之,当 Cache 自身设置了某种容量的限制时,在对应类型的容量限制上将使用自身的限制,如某 Cache 自身设置了 maxBytesLocalHeap 100M ,那么它能够使用的堆内存的最大量就是 100M 。而当 Cache 自身没有指定某种类型的容量限制时,如果在 CacheManager 级别有指定的话,那么该 Cache 将和其它同样没有指定该类型容量限制的 Cache 一起平分 CacheManager 级别该种类型的容量被指定了该类型容量限制的 Cache 瓜分后剩余的容量,否则其将没有该种类型的容量可用。如当 CacheA 没有指定 maxBytesLocalDisk 限制,而在 CacheManager 级别指定了 maxBytesLocalDisk 限制为 10G ,如果在该 CacheManager 内还有另外一个 CacheB 指定了 maxBytesLocalDisk 限制为 5G ,那么 CacheA 将能够使用的 disk 容量为 5G ,如果此时还有另外 N Cache 也没有指定 maxBytesLocalDisk 限制的话,那么它们将和 CacheA 一起瓜分 CacheManager disk 容量 10G 除去 CacheB disk 容量 5G 后剩余的 5G ,即各 5/(N+1)G 。如果 CacheManager 级别也没有指定 maxBytesLocalDisk 的话,那么 CacheA 和其它同样没有指定 maxBytesLocalDisk Cache 将不能使用 disk 进行 Cache 信息的存储(这里是假设这些 Cache 同样都没有指定 maxEntriesLocalDisk )。关于这块如果还有不懂的,可以参考第四小节“配置大小示例”中示例。

 

(本文是基于 Ehcache2.8.1 所写)

Ehcache(04)——设置缓存的大小


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论