ehcahce的diskSpoolBufferSizeMB参数解析,不能过大

本文详细分析了在Ehcache缓存中将diskSpoolBufferSizeMB配置过大使缓存存储速度异常缓慢的问题,并揭示了其背后的原理。通过深入研究Ehcache源代码,发现配置值超出正整数范围导致误判缓存已满,从而触发暂停机制,最终导致生产效率下降。建议遵循官方推荐设置以避免此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 前段时间在项目中使用ehcache做缓存,由于数据量比较大我想调大diskSpoolBufferSizeMB来提高ehcache的存储速度,结果调大到2GB以上,ehcache的放入速度变得异常缓慢,在网上找了好久也没找到原因,今天终于找到原因所在。由于diskSpoolBufferSizeMB在内部实际是以字节为单位,2GB已经超过正整数表示的范围,导致diskSpoolBufferSizeMB为负数,在put时ehcache误以为磁盘缓存队列已满,每次都执行暂停50ms,哭

 

      在DiskStorageFactory类

    

Java代码   收藏代码
  1. // 计算队列大小 spoolBufferSize*1024*1024 注意这里没有做正整数溢出判断  
  2. this.queueCapacity = cache.getCacheConfiguration().getDiskSpoolBufferSizeMB() * MEGABYTE;   
  3.   
  4. // 判断缓存是否已满  
  5. public boolean bufferFull() {  
  6.         // 如果发生正整数溢出,则这里总是返回true,也就误报缓存已满  
  7.         return (diskQueue.size() * elementSize) > queueCapacity;   
  8. }  

 

 

 

     在Cache里有判断磁盘缓存已满,如果满则休眠一小段时间默认是50毫秒再执行,减慢生产线程放入的速度

     

Java代码   收藏代码
  1. /** 
  2.      * wait outside of synchronized block so as not to block readers 
  3.      * If the disk store spool is full wait a short time to give it a chance to 
  4.      * catch up. 
  5.      * todo maybe provide a warning if this is continually happening or monitor via JMX 
  6.      */  
  7.     private void backOffIfDiskSpoolFull() {  
  8.   
  9.         if (compoundStore.bufferFull()) { // 调用的是DiskStorageFactory的bufferFull方法  
  10.             // back off to avoid OutOfMemoryError  
  11.             try {  
  12.                 Thread.sleep(BACK_OFF_TIME_MILLIS);  
  13.             } catch (InterruptedException e) {  
  14.                 Thread.currentThread().interrupt();  
  15.             }  
  16.         }  
  17.     }  

 

     

    在Cache类里每个put方法都会去调用backOffIfDiskSpoolFull方法,内部的一个put方法的代码为

    

   

Java代码   收藏代码
  1. private void putInternal(Element element, boolean doNotNotifyCacheReplicators, boolean useCacheWriter) {  
  2.         // 。。。。。  
  3.         applyDefaultsToElementWithoutLifespanSet(element);  
  4.         backOffIfDiskSpoolFull(); // 执行是否暂停  
  5.         element.updateUpdateStatistics();  
  6.         // 。。。。。  
  7.     }  

 

    这可能是Ehcache开发人员疏漏的整数溢出检查,diskSpoolBufferSizeMB配置超过2GB,queueCapacity为负数,每次元素放入都会暂停50ms,导致速度异常缓慢。一般情况默认值就可以满足需求不需要调整diskSpoolBufferSizeMB的大小。

 

 

        diskSpoolBufferSizeMB官方稳定的解释。

  diskSpoolBufferSizeMB:

    This is the size to allocate the DiskStore for a spool buffer. Writes are made

    to this area and then asynchronously written to disk. The default size is 30MB.

    Each spool buffer is used only by its cache. If you get OutOfMemory errors consider

    lowering this value. To improve DiskStore performance consider increasing it. Trace level

    logging in the DiskStore will show if put back ups are occurring.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值