我的要求是有基于磁盘的缓存。如果缓存内存已满,我希望将LRU元素推送到磁盘。然后,如果磁盘上的文件已满,我希望驱逐磁盘上的LRU元素。这是一个非常简单的要求,但是我无法使用EhCache来实现。
我使用EhCache(2.10.1)进行以下配置:
<defaultCache name="default"
maxBytesLocalHeap="50m"
maxBytesLocalDisk="100g"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
我的期望是,当缓存被填满时(即缓存大小超过50M),我希望将LRU元素推送到文件中,从而为内存中的新元素创建一些空间。
然而,这不是EhCache的工作方式,我做了一个示例测试来检查缓存中的元素计数:
公共静态 void main(String[] args) 抛出异常 {
ArrayList<String> keys = new ArrayList<String>();
CacheManager cacheManager;
FileInputStream fis = null;
try {
fis = new FileInputStream(
new File("src/config/ehcache.xml").getAbsolutePath());
cacheManager = CacheManager.newInstance(fis);
}
finally {
fis.close();
}
java.lang.Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
try
{
System.out.println("Shutting down Eh Cache manager !!");
cacheManager.clearAll();
cacheManager.shutdown();
System.out.println("done !!");
}catch(Exception e)
{
e.printStackTrace();
}
}
});
System.out.println("starting ...");
System.out.println(System.getProperty("java.io.tmpdir"));
cacheManager.addCache("work_item_111");
Cache ehCache = cacheManager.getCache("work_item_111");
long start_outer = System.currentTimeMillis();
for(int i =0;i<30;i++)
{
long start = System.currentTimeMillis();
String key = UUID.randomUUID().toString();
ehCache.put(new Element(key, getNextRandomString()));
keys.add(key);
//System.out.println("time taken : " + (System.currentTimeMillis()- start));
System.out.println((System.currentTimeMillis()- start) +" - " + (ehCache.getStatistics().getLocalDiskSizeInBytes()/1024/1024) + " - " +(ehCache.getStatistics().getLocalHeapSizeInBytes()/1024/1024));
}
System.out.println("time taken-total : " + (System.currentTimeMillis()- start_outer));
System.out.println(ehCache.getSize());
System.out.println("disk size : " +ehCache.getStatistics().getLocalDiskSizeInBytes()/1024/1024);
System.out.println("memory size : " +ehCache.getStatistics().getLocalHeapSizeInBytes()/1024/1024);
Iterator<String> itr = keys.iterator();
int count =0;
while(itr.hasNext())
{
count++;
String key = itr.next();
if(ehCache.get(key) == null)
{
System.out.println("missingg key : " + key);
}
}
System.out.println("checked for count :" + count);
}
在将30个元素放入缓存后(每个元素的大小大约为。4mb),我只能在缓存中看到7个元素(ehCache.getSize()返回7),并且我也没有看到磁盘上的文件在增长。
如果我在这里遗漏了什么,任何EhCache专家都能帮我吗。谢谢
首先,关于EhCache拓扑:
这意味着它不再是一个溢出模型。
现在,关于为什么您的测试行为与您预期的不同:
因此,为了更好地了解正在发生的事情,请查看调试中的Ehcache日志,看看到底发生了什么。如果看到逐出,只需以较慢的速度循环或增加磁盘写入队列的某些设置,例如缓存元素上的 diskSpoolBufferSizeMB
属性。
面临同样的问题。在循环中,我使用缓存配置添加了10k个元素
cacheConfiguration.maxBytesLocalHeap(1, MemoryUnit.MEGABYTES);
cacheConfiguration.diskSpoolBufferSizeMB(10);
// cacheConfiguration.maxEntriesLocalHeap(1);
cacheConfiguration.name("smallcache");
config.addCache(cacheConfiguration);
cacheConfiguration.setDiskPersistent(true);
cacheConfiguration.overflowToDisk(true);
cacheConfiguration.eternal(true);
当maxBytesLocalHeap增加到10时,它是好的,当使用maxEntriesLocalHeap而不是maxBytes并且它甚至被设置为值1 (item)时,它工作起来没有问题。
版本 2.6
这是Ehcache设置为永恒但无论如何都会忘记元素吗?