Как настроить gemfire для диспетчера кеш-памяти Spring без явного определения регионов?

У меня есть приложение Spring, использующее кеширование Spring на основе кеша Guava. В связи с высокими требованиями к пропускной способности и функцией обратной записи мы сейчас рассматриваем возможность перехода на Gemfire. Я успешно настроил Gemfire в качестве кеша и могу читать и писать из кеша. Во всех примерах конфигурации конфигурация требует определения LocalRegionFactory, как показано ниже:

    @Bean
    public Region<Long,Person> myPersonRegion(LocalRegionFactoryBean<Long, Person> personRegion) throws Exception {

        return personRegion.getObject();


    }

    @Bean
    public LocalRegionFactoryBean<Long, Person> personRegion(GemFireCache cache,AsyncEventQueue gemfireQueue) {
        LocalRegionFactoryBean<Long, Person> personRegion = new LocalRegionFactoryBean<>();
        personRegion.setCache(cache);
        personRegion.setClose(false);
        personRegion.setName("person");
        personRegion.setAsyncEventQueues(new AsyncEventQueue[]{gemfireQueue});
        personRegion.setPersistent(false);
        return personRegion;

    }

После определения bean-компонентов мы можем использовать @Cacheable (value = "person"), @CacheEvict (value = "person"). Если мы напрямую используем имя кеша, gemfire выдаст ошибку, что кеш не определен.

Наш опыт работы с Guava (или Hazelcast, redis и т. Д.) Показывает, что нам не нужно явно определять кеши. Он будет автоматически создан весной при первом появлении.

Есть ли способ настроить gemfire таким же образом?


person Sandheep    schedule 06.09.2016    source источник


Ответы (1)


Короткий ответ: НЕТ. не совсем.

Я также не совсем уверен, что ваше следующее утверждение полностью верно ...

Наш опыт работы с Guava (или Hazelcast, redis и т. Д.) Показывает, что нам не нужно явно определять кеши.

Что касается Hazelcast, я знаю, что это неверно из недавний опыт (см. конфигурация и, в частности, эта строка). Строка 78 абсолютно необходима (в той или иной форме, например, в качестве альтернативы XML); без него Spring Cache Abstraction вызовет исключение.

Хотя я не тестировал Redis в качестве поставщика кэширования, похоже, что Redis может обрабатывать динамическое Cache создание (также это).

Вполне вероятно, что Guava, как и ConcurrentMapCacheManager, не требует уже существующего _ 3_ будет явно определен, поскольку ConcurrentMapCacheManager будет динамически создавать Cache (a ConcurrentHashMap) во время выполнения по запросу если НЕ "названо" явно. Однако, если Caches явно названы заранее, то будет сгенерировано исключение, если Cache еще не определен (то есть «назван»).

У меня есть примеры и тесты других провайдеров кеширования здесь, которые иллюстрируют различные и довольно уникальные UC Spring Cache Abstraction на практике, идентифицируемые по именам тестового класса или тестового примера.

Однако во всех тестовых примерах Pivotal GemFire ​​или Apache Geode необходимо явно создать регион, который будет служить «Cache» в инфраструктуре кэширования Spring. Хотя реализация SDG GemfireCacheManager будет динамически создать объект Spring Cache (поддерживаемый базовым регионом), который требуется для Spring AOP CacheInterceptor.

В результате получается следующая минимальная необходимая конфигурация для включения кэширования с использованием GemFire ​​/ Geode в качестве поставщика ...

@SpringBootApplication
@EnableCaching
class MyCachingApplication {

  public static void main(String[] args) {
    SpringApplication.run(MyCachingApplication.class, args);
  }

  @Bean
  GemfireCacheManager cacheManager(GemFireCache gemfireCache) {
    GemfireCacheManager cacheManager = new GemfireCacheManager();
    cacheManager.setCache(gemfireCache);
    return cacheManager;
  }

  // define all Region beans required by the application including Regions
  // used specifically in Spring's Cache Abstraction
}

Теперь, сказав это, я создал прототип динамического создания региона на основе аннотаций Spring Cache Abstraction (например, @Cacheable), используемых во всех объявленных компонентах приложения [службы], как можно увидеть, начиная с этого test. Вот конфигурация.

Как видите, НЕТ явных определений bean-компонентов для регионов GemFire, которые будут служить Caches в инфраструктуре кэширования Spring. Тем не менее, компонент Spring @Service приложения (теста) делает использовать кеширование.

Создание динамической области выполняется с помощью Spring _ 17_ (здесь) и функции GemFire ​​(с использованием поддержки аннотаций функций SDG) для динамического создания регионов во время выполнения, во время запуска. Выполнение функции: определен здесь, а фактическая реализация функции - определено здесь.

Этот пример довольно грубый (т.е. не обрабатывает настраиваемую конфигурацию региона (например, исключение / истечение срока, сохранение, переполнение и т. Д.) За пределами DataPolicy) и в настоящее время настроен для обработки топологии однорангового кеша (т.е. тестовое приложение является одноранговым членом / узлом в GemFire ​​DS).

Однако довольно легко расширить этот прототип для использования в топологии клиент / сервер, учесть все аннотации кеширования Spring и JSR-107 и разрешить больше настраиваемых областей конфигурация.

Со временем это, возможно, я добавлю к самой структуре ЦУР.

Надеюсь это поможет.

Привет, Джон

person John Blum    schedule 06.09.2016
comment
Очень признателен за подробное объяснение, которое вы предоставили. Я буду опробовать тесты и метод BeatPostProcessor. Еще несколько моментов: 1. Hazelcast поддерживает создание динамического кеша. Пожалуйста, прочтите приведенную ниже суть [ссылка] (gist.github.com/sandheepgr/c715ce530a14918834a). Это была тестовая установка, и она так и не была запущена для нас. 2. Есть ли специальный режим для конфигурации с обратной записью. Я определил писателя и загрузчика, и он немедленно записывает в db (также возможно с использованием async). Но не объединяет данные для записи только последнего обновления. - person Sandheep; 07.09.2016
comment
Привет @ Sandheep. Я все еще скептически отношусь к тому, что Hazelcast будет динамически создавать кеши. Ему нужен хотя бы какой-то DistributedObject (распределенная структура данных), например Map. Даже источник HazelcastCacheManger (github.com/hazelcast/hazelcast/blob/master/hazelcast-spring/src/) указывает, что Spring Cache очень много существует. Одно отличие может заключаться в том, что вы создали клиентский экземпляр Hazelcast (строка 44), который подключается к некоторому существующему кластеру, где карта, вероятно, уже определена. Потом... - person John Blum; 07.09.2016
comment
CacheManager Hazelcast легко может найти и найти (удаленный) DistributedObject (github.com/hazelcast/hazelcast/blob/master/hazelcast-spring/src/). Разница в моей конфигурации заключается в том, что HazelcastInstance, созданный Boot (github.com/spring-projects/spring-boot/blob/v1.4.0.RELEASE/) на самом деле это встроенный узел данных без ранее существовавших структур данных ... - person John Blum; 07.09.2016
comment
Что касается №2, посмотрите здесь (gemfire.docs .pivotal.io / docs-gemfire / latest / Developing /), обсуждая, как работают загрузчики данных (т.е. CacheLoader). Также обратите внимание на это (gemfire.docs.pivotal.io / docs-gemfire / develop / events /), чтобы узнать больше об асинхронной записи и отложенной записи. Для получения дополнительной информации о том, как события работают в GemFire, см. Здесь (gemfire.docs.pivotal.io/docs-gemfire/developing/events/). Если после этого у вас возникнут дополнительные вопросы, дайте мне знать. - person John Blum; 07.09.2016
comment
Примечание (вкратце) с GemFire ​​AsyncEventQueue (data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/) вы можете как группировать, так и объединять свои входные события, поэтому, по сути, он записывает только последнее обновление, когда запускает прослушиватель AEQ, где вы можете выполнять обратную запись в свою БД. С CacheLoader это полностью синхронно и 1 к 1 с операцией кеширования региона (например, Region.put(key, value)). Надеюсь это поможет. Прочтите документацию и дайте мне знать. Ваше здоровье. - person John Blum; 07.09.2016
comment
Спасибо, Джон :). У меня запущен образец установки (github.com/sandheepgr/spring-gemfire-sample). Я понимаю, что у асинтаксической задачи есть пакетная поддержка. Применимо ли это также к CacheWriter ?. Я видел пример на вашем github, который реализует обратную запись с использованием @Async для Cache Writer. В основных документах gemfire обратная запись объясняется с помощью AsyncEventListener и AsyncEventQueue. Они разные по поведению? - person Sandheep; 08.09.2016