1

我们有一个包含 n 个客户端(目前为 55 个)的系统,其中每个客户端都有自己的数据库,所有这些数据库都具有完全相同的模式。我们正在运行由分布式 ehcache 支持的休眠 3.6.1。这已通过 SessionFactoryService 使用每个数据库的 SessionFactory 实现,该 SessionFactoryService 在运行时“懒惰地”为每个 jvm 的每个客户端创建一个 SessionFactory(存储在 HashMap 中),因此我们正在运行一组应用程序管理的 SessionFactories。有一个基本的休眠配置文件,其余设置在创建时以编程方式完成。我们的存储库(或者更常见的 DAO)可以通过 SessionFactoryService 访问 SessionFactory。我们充分利用了由分布式 SingltonEhcacheRegionFactory 支持的休眠二级缓存。因为我们在每个 jvm 运行 n 个 SessionFactories,所以我们不想要一个 NON SingltonEhacheRegionFactory(即每个 SessionFactory 有一个 CacheManager),因为在尝试保持缓存之间的同步时,Se​​ssionFactories 之间会有太多的 jvm 间通信。所以我们想要的只是跨服务器的通信,而不是服务器内的通信,这是通过 SingltonEhcacheRegionFactory 实现的。

现在,这里是乐趣的开始。使用上述设置,将存在缓存冲突,因为无法保证唯一键作为数据库模式,因此支持它们的实体对象在 SessionFactories 中是相同的。为了使它们独一无二,我们通过上面的编程配置步骤将字段 hibernate.cache.region_pre-fix 设置为每个 SessionFactory 的唯一值。这满足了 Hibernate 对二级缓存的看法,但底层的单例 ehcache 现在存在问题。它找不到正确的配置,因为 ehache.xml 配置文件中指定的配置在缓存名称上没有缓存前缀(也不能,因为每个前缀的每个缓存配置都必须有一个重复条目,其中有n个)。这会导致以下错误:

10:37:38,389 WARN AbstractEhcacheRegionFactory:201 - 在 Hibernate 配置中找不到 TransactionManagerLookup,XA 缓存将参与两阶段提交!10:37:39,675 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.adc] 的缓存的特定 ehcache 配置;使用默认值。10:37:40,328 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.org.hibernate.cache.UpdateTimestampsCache] 的缓存的特定 ehcache 配置;使用默认值。10:37:40,331 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.org.hibernate.cache.StandardQueryCache] 的缓存的特定 ehcache 配置;使用默认值。

那么问题来了,我们如何才能在每个 jvm 环境中使用分布式单例 ehcache 来完成多个 SessionFactory?有没有办法将 ehcache 配置为区域前缀感知?我们实施的解决方案充其量只是hacky。我们已经实现了自己的 hibernate.cache.region.factory_class,它扩展了 SingltonEhcacheRegionFactory(并删除了 hibernate 缓存区域前缀配置)。我们的实现所做的只是拦截对底层 Ehcache 的方法调用,并为所有用于缓存操作的键附加一个前缀,从而防止缓存冲突。我们想要一个更“开箱即用”的解决方案,出于显而易见的原因,尽管它有效,但我们实施的方案并不理想。我已经阅读了我可能找到的关于此事的所有内容,但没有 t 找到了一个解决方案,该解决方案使用分布式二级缓存使用相同的模式(最重要的是)处理多个 SessionFactories。任何想法、解决方案或建议将不胜感激。如果有人有解决需求的好方法,我什至对完全不同的设计持开放态度。提前致谢!

4

1 回答 1

0

使用上述设置,将存在缓存冲突,因为无法保证唯一键作为数据库模式,因此支持它们的实体对象在 SessionFactories 中是相同的

你是什​​么意思?如果您为所有客户端使用相同的模式,那么肯定有一种方法可以保证唯一的键。为此有很多技术,包括使用 UUID 或使用 Hibernate 的 hilo 算法。

为了使它们唯一,我们通过上面的编程配置步骤将字段 hibernate.cache.region_pre-fix 设置为每个 SessionFactory 的唯一值

不确定我是否理解。您的意思是为了能够获得唯一的键,您需要不同的缓存区域?如果是这样,那不是真的 :-) 缓存区域应该是实体(汽车、人、帐户)的“命名空间”,而不是条目(汽车#1、汽车#2)。

我们如何在每个 jvm 环境中使用分布式单例 ehcache 完成多个 SessionFactory?

多个会话工厂不是问题。不确定ehcache,但我会考虑使用“缓存服务器”,比如Infinispan。您可以在它自己的 JVM 中启动它,并且所有客户端在他们想要访问缓存时都会与它交谈。同样,不确定我是否正确理解了您的环境,但是在使用缓存时,您应该使用确保 Client#1 看到的数据与 Client#2 相同的设置。

因此,我将设置一个带有专用缓存服务器的环境,配置所有会话工厂以使用它。此外,您在描述中遗漏的一点是事务管理器。在处理分布式环境时,事务管理非常重要,以确保缓存(和数据库)中的数据不会过时并且是一致的。

你可以在这里阅读更多关于 Infinispan 和 Hibernate 的信息:http: //community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider

于 2011-03-17T08:02:37.843 回答