EH-Cache с менеджером Spring Cache не работает должным образом

У нас есть веб-приложение java на основе весны (3.2.9.Release) и мы используем спящий режим для операций с БД. В настоящее время у нас есть механизм кэширования с использованием Dynacache, который настраивается через сервер WebSphere и использует сопоставление jndi. Мы извлекаем весь контент из базы данных при загрузке первой страницы и сохраняем его в Dynacache. Поскольку каждый раз это внешний вызов, мы хотели внедрить Eh-Cache и повысить производительность. Но на удивление производительность Eh-Cache меньше, чем у Dynacache, и загрузка страницы занимает много времени. Ниже приведена конфигурация, которая была у нас для Eh-Cache:

конфигурация XML:

<bean id="cacheService" class="com.wlp.sales.ols.core.api.cache.CacheService"></bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache" />
    </bean>

<bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="/WEB-INF/configs/EhCache/ehcache.xml" />
        <property name="shared" value="true" />

ehcache.xml

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">

    <cache name="contentCache" 
        maxEntriesLocalHeap="10000"
        maxEntriesLocalDisk="1000" 
        eternal="true" 
        diskSpoolBufferSizeMB="20"
        timeToIdleSeconds="0" timeToLiveSeconds="0"
        memoryStoreEvictionPolicy="LRU" 
        transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache> 

зависимости:

<!-- ehCache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

У нас есть класс реализации кеша, который будет генерировать ключ кеша, используя методы get и put для извлечения из базы данных и помещения в карту кеша в виде пары ключ-значение.

public Object get(CdiRequest request) {
        Object cdiObject = cacheService.get(request.getContentElement()
                .getContentType(), keyBuilder.build(request));
        return cdiObject instanceof CdiResponse ? (CdiResponse) cdiObject
                : request;
}

//Реализация метода Put:

cacheService.put(cdiResponse.getCdiRequest().getContentElement()
                    .getContentType(),
                    keyBuilder.build(cdiResponse.getCdiRequest()), cdiResponse);

Класс реализации:

 public class CacheService implements ApplicationContextAware{
    @Autowired
    private CacheManager cacheManager;
    private ApplicationContext applicationContext;

    public Object get(String applnName, Object key) {

            Cache  cache = cacheManager.getCache("contentCache");
            return cache.get(key);
      }

      public boolean put(String applnName, Object key, Object value) {
          Cache  cache =  cacheManager.getCache("contentCache");
          cache.put(key, value);
          return true;
      }
}

Загрузка каждой страницы при обновлении или перезагрузке занимает от 60 до 80 секунд, тогда как динамическому кэшированию требуется всего 3-4 секунды. Пожалуйста, сообщите, если что-то делается неправильно или можно сделать лучше.


person RVR    schedule 04.02.2016    source источник


Ответы (2)


Почему вы не хотите предоставлять стандартные аннотации для Cache в Spring и использовать их в методе получения значений из БД?:

@Cacheable(value="contentCache", key="#name")

Итак, вы можете получить свой контент из БД и сохранить в кеше? Если что-то изменится, вы можете использовать CacheEvict.

person m.aibin    schedule 04.02.2016
comment
что произойдет, если я попробую так же, как @Cacheable(value=contentCache)... можете ли вы сказать мне значение ключа в этом случае - person RVR; 04.02.2016
comment
Нужно поставить ключ. Без ключа он покажет вам ошибку. - person m.aibin; 04.02.2016
comment
я реализовал, как вы упомянули ... без ключа, он не показал мне никакой ошибки ... тем не менее я вызвал кешируемую аннотацию к моему методу dao следующим образом: @Cacheable (value = contentCache, key = # name), а также попытался использовать: @Cacheable ( value=contentCache, key=#methodName) methodName — генерирует мой пользовательский ключ. У меня был sysout внутри моего метода dao, чтобы проверить, печатается ли он даже при перезагрузке или обновлении.. его печать при каждой загрузке страницы или обновлении, что означает, что это не так. беру из contentcache .. есть ли что-то, что я все еще ошибаюсь? - person RVR; 04.02.2016
comment
С этой реализацией я полностью удалил ссылку на cacheService. У меня есть только зависимости в моей конфигурации pom.xml, ehcache.xml и xml bean. Как я упоминал в своем предыдущем комментарии, я напрямую вызываю эту аннотацию к моему методу dao, который извлекает содержимое из моей базы данных. - person RVR; 04.02.2016

Есть несколько вещей, которые можно улучшить:

  1. At the configuration level
    • Do you really need the disk store? It adds overhead as content must be serialized / deserialized.
    • Если вам это нужно, вам нужно увеличить дисковое хранилище больше, чем в куче, так как все сопоставления будут существовать в дисковом хранилище. Таким образом, с текущей конфигурацией вы фактически ограничиваете размер кучи до 1000.
  2. На уровне использования вы эффективно используете кеш как хранилище в памяти, потому что у вас нет логики для обработки случая, когда сопоставление не найдено. Теперь, возможно, то, что вы кэшируете, является известным набором ключей и меньше размера, который вы установили. Тем не менее, это может быть более поздней причиной проблем.

Что касается проблем с производительностью, вам нужно будет предоставить более подробную информацию, если вам нужна помощь в отслеживании проблемы.

person Louis Jacomet    schedule 04.02.2016
comment
Большое спасибо за ответ. . - person RVR; 05.02.2016
comment
Дополнительный контекст: вызванный код, некоторые тайминги, журналы, указывающие на эффективное использование кеша. Короче говоря, все, что устраняет проблему с конфигурацией / настройкой, и четкие указания на то, что вызовы, связанные с кешем, на самом деле постоянно горят. - person Louis Jacomet; 09.02.2016