ehcache persist to disk issues

后端 未结 8 1753
你的背包
你的背包 2020-12-23 14:30

I want to do something with ehcache in Java that I think should be extremely simple, but I\'ve spent enough time frustrating myself with the docs...

  1. Write a

8条回答
  •  时光取名叫无心
    2020-12-23 15:24

    After spending some quality time with the debugger, I believe I have an answer for the OP.

    The issue (at least from what I have seen) centers around the non-clustered disk cache files and how they get read back in. In the file net.sf.ehcache.store.compound.factories.DiskPersistentStorageFactory.java, the method:

    public DiskPersistentStorageFactory(Ehcache cache, String diskPath) {
        super(getDataFile(diskPath, cache), cache.getCacheConfiguration().getDiskExpiryThreadIntervalSeconds(),
                cache.getCacheConfiguration().getDiskSpoolBufferSizeMB(), cache.getCacheEventNotificationService(), false);
    
        indexFile = new File(getDataFile().getParentFile(), getIndexFileName(cache));
        flushTask = new IndexWriteTask(indexFile, cache.getCacheConfiguration().isClearOnFlush());
    
        if (!getDataFile().exists() || (getDataFile().length() == 0)) {
            LOG.debug("Matching data file missing (or empty) for index file. Deleting index file " + indexFile);
            indexFile.delete();
        } else if (getDataFile().exists() && indexFile.exists()) {
            if (getDataFile().lastModified() > (indexFile.lastModified() + TimeUnit.SECONDS.toMillis(1))) {
                LOG.warn("The index for data file {} is out of date, probably due to an unclean shutdown. " 
                        + "Deleting index file {}", getDataFile(), indexFile);
                indexFile.delete();
            }
        }
    
        diskCapacity = cache.getCacheConfiguration().getMaxElementsOnDisk();
        memoryCapacity = cache.getCacheConfiguration().getMaxElementsInMemory();
        memoryPolicy = determineEvictionPolicy(cache.getCacheConfiguration());
    }
    

    checks the timestamps on the data files. The problem I am seeing is that no matter how I end up shutting down the cache/manager, the files are never get synchronized properly. My quick and dirty workaround was to adjust the time of the data file to be just past the timestamp on the index file:

    File index = new File( path, name + ".index" );
    File data  = new File( path, name + ".data"  );
    
    data.setLastModified( index.lastModified() + 1 );
    

    Granted, this is not elegant, but it serves my needs, as our project uses clustered caches, and this allows me to debug standalone with a persistent cache...and without having to actually run Terracotta locally.

    One caveat is that for non-clustered caches, I do have to flush() after every put() and remove() in order to keep the disk image fresh, especially when debugging due to the lack of shutdown support when you just "pull the plug".

提交回复
热议问题