6

アプリケーションにロードするのに非常にコストがかかるオブジェクトをキャッシュするために、Ehcache を使用しています。起動時に、必要なすべてのオブジェクトをキャッシュし、別のプロセスによって 1 日 1 回更新されます。

ただし、オブジェクトをキャッシュに追加した直後に、オブジェクトが消えるようです。削除されたと報告されているものは何もありませんが、何らかの理由でオブジェクトがキャッシュに保持されていません。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 の構成が間違っているのでしょうか、それともコードにバグがありますか? どんな助けでも大歓迎です。ありがとう。

spring 3.1.0、ehcache-spring-annotations 1.1.2、および ehcache 2.4.2 を使用しています。

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" />
4

1 に答える 1

6

diskPersistenttrue に設定されていたためEhcache、オブジェクトがキャッシュに追加された後にオブジェクトをディスクに書き込もうとしていました。ただし、メインのキャッシュ オブジェクト内のネストされたオブジェクトの 1 つは を実装していなかったSerializableため、ディスク書き込み時に例外をスローし、キャッシュからオブジェクトを削除していました。によって削除されなかったため、この削除はキャッシュ統計に表示されませんでしたmemoryStoreEvictionPolicy

これは非常に見つけやすいバグだったはずですが、プロジェクトにはslf4j-log4j12ライブラリが含まれていなかったため、例外はログに書き出される代わりに飲み込まれていました。ロギングが適切に処理されると、問題が何であるかがすぐに明らかになりました。

まあ、生きて学べばいいんだけど…

于 2012-09-02T11:54:06.507 に答える