`
zymming6
  • 浏览: 2836 次
社区版块
存档分类
最新评论

ehcahce的diskSpoolBufferSizeMB参数解析

阅读更多

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

 

      在DiskStorageFactory类

    

// 计算队列大小 spoolBufferSize*1024*1024 注意这里没有做正整数溢出判断
this.queueCapacity = cache.getCacheConfiguration().getDiskSpoolBufferSizeMB() * MEGABYTE; 

// 判断缓存是否已满
public boolean bufferFull() {
        // 如果发生正整数溢出,则这里总是返回true,也就误报缓存已满
        return (diskQueue.size() * elementSize) > queueCapacity; 
}

 

 

 

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

     

/**
     * wait outside of synchronized block so as not to block readers
     * If the disk store spool is full wait a short time to give it a chance to
     * catch up.
     * todo maybe provide a warning if this is continually happening or monitor via JMX
     */
    private void backOffIfDiskSpoolFull() {

        if (compoundStore.bufferFull()) { // 调用的是DiskStorageFactory的bufferFull方法
            // back off to avoid OutOfMemoryError
            try {
                Thread.sleep(BACK_OFF_TIME_MILLIS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

 

     

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

    

   

private void putInternal(Element element, boolean doNotNotifyCacheReplicators, boolean useCacheWriter) {
        // 。。。。。
        applyDefaultsToElementWithoutLifespanSet(element);
        backOffIfDiskSpoolFull(); // 执行是否暂停
        element.updateUpdateStatistics();
        // 。。。。。
    }

 

    这可能是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.

 

   

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics