2012-09-01 86 views
6

我正在使用Ehcache来缓存在我的应用程序中加载非常昂贵的对象。在启动时,我缓存所有需要的对象,并且每天通过单独的进程刷新一次。Ehcache丢失对象

但是,看来在我将对象添加到缓存后不久,它们就消失了。没有报道被驱逐,但由于某些原因,这些对象不会在缓存中持久。当我运行ObjectLoader.loadCache(),这是我收到的输出:

2012-09-01 17:25:37,121 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:25:37,121 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 0 
2012-09-01 17:25:37,121 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 501 
2012-09-01 17:26:17,271 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:26:17,271 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:26:17,274 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 501 
2012-09-01 17:26:17,274 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:26:17,274 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 1 
2012-09-01 17:26:17,274 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 518 
2012-09-01 17:26:35,894 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:26:35,895 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:26:35,895 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 518 
2012-09-01 17:26:35,895 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:26:35,895 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 1 
2012-09-01 17:26:35,895 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 516 
2012-09-01 17:27:31,997 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:27:31,998 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:27:31,998 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 516 
2012-09-01 17:27:31,998 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:27:31,998 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 1 
2012-09-01 17:27:31,998 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 515 
2012-09-01 17:28:20,343 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:28:20,343 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:28:20,344 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 515 
2012-09-01 17:28:20,344 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:28:20,344 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 1 
2012-09-01 17:28:20,344 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 525 
2012-09-01 17:29:05,616 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:29:05,617 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:29:05,617 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 525 
2012-09-01 17:29:05,617 [main] DEBUG ObjectLoader.getObject():65 - ************************************ 
2012-09-01 17:29:05,617 [main] DEBUG ObjectLoader.getObject():66 - Number of objects in cache: 1 
2012-09-01 17:29:05,618 [main] DEBUG ObjectLoader.getObject():72 - Object not in cache | 512 
2012-09-01 17:29:38,790 [main] DEBUG ObjectLoader.getObject():80 - Number of objects in cache: 1 
2012-09-01 17:29:38,790 [main] DEBUG ObjectLoader.getObject():81 - Number of objects evicted from cache: 0 
2012-09-01 17:29:38,790 [main] DEBUG ObjectLoader.getObject():83 - Object key found: 512 

难道我的Ehcache配置错误或者我在我的代码中的错误?任何帮助,将不胜感激。谢谢。

我使用的弹簧3.1.0,ehcache的弹簧批注1.1.2和2.4.2的Ehcache

ObjectCacheFacade.java

@Component() 
public class ObjectCacheFacade { 
    private static final String CACHE_KEY = "myObjectCache"; 

    @Resource 
    private CacheManager cacheManager; 
    private Cache cache; 

    public ObjectCacheFacade() { 
     cacheManager = CacheManager.getInstance(); 
     this.cache = cacheManager.getCache(CACHE_KEY); 
    } 

    public Object getObjectFromCache(String objectId) { 
     Object result = null; 
     Element element = cache.get(objectId); 

     if (element != null && element.getValue() != null) { 
      result = element.getObjectValue(); 
     } 

     return result; 
    } 

    public void putObjectIntoCache(String objectId, Object object) { 
     Element element = new Element(objectId, object); 
     cache.put(element); 
    } 

    public int getSize() { 
     return cache.getSize(); 
    } 

    public void removeObjectFromCache(String objectId) { 
     cache.remove(objectId); 
    } 

    public void flushCache() { 
     cache.removeAll(); 
    } 

    public Cache getCache() { 
     return cache; 
    } 
} 

ObjectLoader.java

@Service 
public class ObjectLoader { 
    private static final Logger log = Logger.getLogger(ObjectLoader.class); 

    @Resource 
    protected ObjectDao objectDao; 
    @Resource 
    protected ObjectCacheFacade objectCache; 

    public void loadCache() { 
     List<String> objectIds = objectDao.getObjectIds(); 

     for (String objectId : objectIds) { 
      loadObject(objectId); 
     } 
    } 

    public Object getObject(String objectId) { 
     log.debug("************************************"); 
     log.debug("Number of objects in cache: " + objectCache.getSize()); 

     Object object = objectCache.getObjectFromCache(objectId); 

     if (object == null) { 
      log.debug("Object not in cache | " + objectId); 
      object = objectDao.getObject(objectId); 

      if (object != null) { 
       objectCache.putObjectIntoCache(objectId, object); 

       log.debug("Number of objects in cache: " + objectCache.getSize()); 
       log.debug("Number of objects evicted from cache: " + objectCache.getCache().getCacheEventNotificationService().getElementsEvictedCounter()); 
       for (Object key : objectCache.getCache().getKeys()) { 
        log.debug("Object key found: " + key); 
       } 
      } 
     } 

     return object; 
    } 
} 

ehcache.xml

<ehcache> 
    <diskStore path="java.io.tmpdir"/> 

    <defaultCache 
     maxElementsInMemory="1000" 
     eternal="false" 
     timeToIdleSeconds="60" 
     timeToLiveSeconds="300" 
     overflowToDisk="false" 
     memoryStoreEvictionPolicy="LRU" 
     /> 

    <cache 
     name="myObjectCache" 
     maxElementsInMemory="1000" 
     eternal="true" 
     timeToIdleSeconds="0" 
     timeToLiveSeconds="0" 
     overflowToDisk="false" 
     diskPersistent="true" 
     memoryStoreEvictionPolicy="LRU" 
     /> 

</ehcache> 

的applicationContext.xml

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> 
+0

我怀疑你想overflowToDisk =“true”。 另外,如果您使用的是EHCache 2.6或更高版本,则应该使用来代替。 查看http://ehcache.org/documentation/configuration/fast-restart – GreyBeardedGeek

回答

5

由于diskPersistent设置为true Ehcache试图写入对象到磁盘,他们添加到缓存后。但是,主缓存对象内的其中一个嵌套对象没有实现Serializable,所以它在磁盘写入时抛出异常,然后从缓存中逐出对象。这种驱逐没有显示在缓存统计中,因为它没有被memoryStoreEvictionPolicy驱逐。

这应该是一个非常容易发现的bug,但该项目不包括slf4j-log4j12库,所以异常被吞噬而不是写入日志。一旦记录得到妥善处理,问题即刻显而易见。

噢,生活和学习我猜...