我正在尝试将项目代码从OSCache迁移到EhCache。
我们不仅将OSCache用作二级Hibernate缓存提供程序,还用于存储其他不同性质的对象。由于非重叠的缓存键,他们都愉快地共享同一个缓存实例而没有任何冲突。
向EhCache迈进时,一个很大的区别是每个区域都有不同的缓存实例。这可能是好的,因为它可以提高查找速度,因为不同性质的数据分开存在。不幸的是,这有配置地狱的代价。让我解释一下。
在OSCache世界中,我将配置我的缓存容量,比方说,10000。现在,如果特定安装需要/可以提供更多RAM,我会轻松地将其增加到50000,这样做。现在在EhCache中,我必须为每个区域更改此delta的部分设置!
此外,一个安装可能对X类型对象的使用率更高,而另一个安装可能更喜欢Y类型对象的更高流失。我们有几十个安装,每个安装都有数百个不同的缓存。为此,除了监控缓存模式和调整设置之外,我们不得不雇佣一大堆人员!
我希望CacheManager
具有某种全局缓存容量设置,并且每个内部缓存都会争取更多容量,具体取决于条目的使用情况。但是,我发现设置缓存容量的唯一方法是通过CacheConfiguration
,这与CacheManager
是多对一的。
到目前为止,我能看到的唯一选择是尝试强制Hibernate为所有实体使用一个全局缓存。有谁知道怎么做?我的方案还有其他更好的解决方案吗?
答案 0 :(得分:2)
您可以尝试使用一个缓存并在其周围添加装饰器。装饰器可以具有与您的区域名称匹配的名称,以便hibernate可以使用这些缓存,但这些装饰器将在下面使用相同的缓存。所以只有一个缓存配置要管理。 您可以通过实现自定义cache decorators并设置装饰缓存的名称来实现此目的。
你可以使用这样的ehcache.xml:
<defaultCache maxElementsInMemory="10000" eternal="false"
overflowToDisk="false"/>
<cache name="singleSharedCache" maxElementsInMemory="2000"
eternal="false" overflowToDisk="false">
<cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory"
properties="name=org.hibernate.tutorial.domain.Person" />
<cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory"
properties="name=org.hibernate.tutorial.domain.Event" />
</cache>
<defaultCache maxElementsInMemory="10000" eternal="false"
overflowToDisk="false"/>
<cache name="singleSharedCache" maxElementsInMemory="2000"
eternal="false" overflowToDisk="false">
<cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory"
properties="name=org.hibernate.tutorial.domain.Person" />
<cacheDecoratorFactory class="com.xyz.util.CustomEhcacheDecoratorFactory"
properties="name=org.hibernate.tutorial.domain.Event" />
</cache>
“com.xyz.util.CustomEhcacheDecoratorFactory”是一个自定义ehcache装饰工厂类,用于创建装饰的ehcaches。您可以使用“properties”属性以您想要的任何方式设置装饰的ehcache,这里您只使用name属性来配置新装饰的ehcache的名称。可以将所有其他操作委派给底层缓存。
提供一个适用于此用例的自定义缓存装饰器,它重用ehcache jar中的EhcacheDecoratorAdapter并覆盖getName()。 EhcacheDecoratorAdapter将所有操作委托给您在构造函数中传递的基础ehcache:
package com.xyz.util; import java.util.Properties; import net.sf.ehcache.Ehcache; import net.sf.ehcache.constructs.CacheDecoratorFactory; import net.sf.ehcache.constructs.EhcacheDecoratorAdapter; public class CustomEhcacheDecoratorFactory extends CacheDecoratorFactory { public Ehcache createDecoratedEhcache(final Ehcache cache, final Properties properties) { return new EhcacheDecoratorAdapter(cache) { private final String name = properties.getProperty("name"); public String getName() { return name; } }; } public Ehcache createDefaultDecoratedEhcache(final Ehcache cache, final Properties properties) { return new EhcacheDecoratorAdapter(cache) { private final String name = properties.getProperty("name"); public String getName() { return name; } }; } }