【问题标题】:How to configure gemfire for spring cache manager without explicitly defining regions?如何在不明确定义区域的情况下为 spring 缓存管理器配置 gemfire?
【发布时间】:2016-09-06 11:37:00
【问题描述】:

我有一个使用基于 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 等)的经验是,我们不需要显式定义缓存。它会在第一次出现时由 spring 自动创建。

有什么方法可以配置 gemfire 以同样的方式运行?

【问题讨论】:

    标签: spring caching spring-cache gemfire spring-data-gemfire


    【解决方案1】:

    简短的回答是;不完全是。

    我也不完全确定您的以下陈述是否完全准确......

    我们使用 Guava(或 Hazelcast、redis 等)的经验是,我们不需要显式定义缓存。

    对于 Hazelcast,我知道 recent experience 不是 true(请参阅 configuration,特别是 this line)。 第 78 行 是绝对必要的(以某种形式或形式,例如 XML);没有它,Spring 的缓存抽象会抛出异常。

    虽然我没有测试 Redis 作为缓存提供程序,但似乎 Redis 可以处理 dynamic Cache creation(也可以是 this)。

    Guava 很可能与 ConcurrentMapCacheManager 实现一样,不需要显式定义预先存在的 Caches,因为 ConcurrentMapCacheManager 将在运行时在请求 @987654329 时 dynamically create the Cache(ConcurrentHashMap) @。但是,如果 Caches 提前明确命名,那么如果 Cache 尚未定义(即“命名”),则会引发异常。

    我有其他缓存提供程序 here 的示例和测试,它们说明了 Spring 的缓存抽象在实践中的不同且相当独特的 UC,由测试类或测试用例名称标识。

    但是,在所有 Pivotal GemFire 或 Apache Geode 测试示例中,您必须明确创建将在 Spring 的 缓存基础架构中用作“Cache”的区域。虽然,SDG 的 GemfireCacheManager 实现将 dynamically create 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
    }
    

    现在,话虽如此,我已经基于整个声明的应用程序 [service] 组件中使用的 Spring Cache Abstraction 注释(例如 @Cacheable)创建了动态区域创建原型,从 test 开始。这是configuration

    如您所见,GemFire 区域没有明确的 bean 定义,它们将在 Spring 的缓存基础架构中充当 Caches。然而,应用程序的(测试的)Spring @Service 组件执行 make use of caching

    动态区域创建是通过使用 Spring BeanPostProcessor (here) 和 GemFire 函数(使用 SDG 的函数注释支持)在运行时和启动期间动态创建区域来完成的。 Function 执行为defined here,实际Function 实现为defined here

    这个例子相当粗糙(即不处理自定义区域配置(例如驱逐/过期、持久性、溢出等)超过DataPolicy)并且当前设置为处理对等缓存拓扑(即测试应用程序是GemFire DS 中的对等成员/节点)。

    然而,扩展这个原型以在客户端/服务器拓扑中使用非常容易,考虑到所有 SpringJSR-107 缓存注释并允许更多自定义区域配置。

    这可能是我添加到 SDG 框架本身的内容。

    希望这会有所帮助。

    干杯, 约翰

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2022-11-11
    • 1970-01-01
    • 2014-04-10
    • 2019-03-04
    • 1970-01-01
    • 2018-05-18
    相关资源
    最近更新 更多