指定全局EhCache容量 [英] Specifying global EhCache capacity

查看:88
本文介绍了指定全局EhCache容量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将我的项目代码从OSCache迁移到EhCache。我们已经将OSCache不仅用作二级Hibernate缓存提供程序,而且还用于存储其他不同性质的物体。他们都愉快地共享相同的缓存实例,没有任何冲突,因为缓存键不重叠。



当向EhCache移动时,一个很大的区别是每个区域都有其不同的缓存实例。这可能是好的,因为它可以提高查找速度,因为不同性质的数据分别存在。不幸的是,这有一个配置地狱的代价。让我解释一下。



在OSCache世界中,我将配置缓存容量为10000,现在如果某个特定安装需要/可以支付更多的RAM ,我很容易把它加到50000,那样做。现在在EhCache中,我必须去改变每个区域的这个增量的一部分!



此外,一个安装可能有更高的X类型对象的使用率,而另一个安装可能更喜欢Y类型对象的更高流失。我们有几十个安装,每个安装都会有数百个不同的缓存。为此,我们不得不雇用一群人,只是无所事事,只能监控缓存模式并调整设置!

我期待 CacheManager code>具有某种全局缓存容量设置,并且每个内部缓存将根据条目使用情况争取更多容量。然而,我发现设置缓存容量的唯一方法是通过 CacheConfiguration ,这对于 CacheManager 是多对一的。

到目前为止,我能看到的唯一选择是尝试强制Hibernate为所有实体使用一个全局缓存。有谁知道如何做到这一点?对于我的场景,还有其他更好的解决方案吗?

解决方案

装饰器可以有与您的区域名称相匹配的名称,以便hibernate可以使用这些缓存,但这些装饰器将使用下面的相同缓存。因此,只有一个缓存配置需要管理。
您可以通过实现自定义缓存修饰器来实现此目的,并设置您的装饰名称

你可以有这样的ehcache.xml:

 < defaultCache maxElementsInMemory =10000eternal =false
overflowToDisk =false/>

< cache name =singleSharedCachemaxElementsInMemory =2000
eternal =falseoverflowToDisk =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。您可以使用属性属性以任何您想要的方式设置装饰的ehcache,此处仅使用name属性来配置新装饰的ehcache的名称。所有其他操作都可以委托给底层缓存。



提供一个用于此用例的自定义缓存修饰器,它将重用ehcache中的EhcacheDecoratorAdapter jar和只是覆盖getName()。 EhcacheDecoratorAdapter将所有操作委托给您在构造函数中传递的基础ehcache:

 

package com.xyz.util;

import java.util.Properties;

导入net.sf.ehcache.Ehcache;
导入net.sf.ehcache.constructs.CacheDecoratorFactory;
导入net.sf.ehcache.constructs.EhcacheDecoratorAdapter;

public class CustomEhcacheDecoratorFactory extends CacheDecoratorFactory {

public Ehcache createDecoratedEhcache(final Ehcache cache,$ b $ final属性){
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( 名称);

public String getName(){
return name;
}
};
}
}


I am trying to migrate my project code from OSCache to EhCache.

We have used OSCache not only as a second-level Hibernate cache provider but also to store other objects of a different nature. They all happily shared the same cache instance without any collisions due to non-overlapping cache keys.

One big difference when moving towards EhCache is that each region has its different cache instance. This is potentially good as it can improve lookup speed as data of the different nature resides separately. Unfortunately, this has a price of configuration hell. Let me explain.

In the OSCache world, I would configure my cache capacity to be, let's say, 10000. Now if a particular installation would require/could afford more RAM, I would easily beef it up to 50000 and that would do. Now in EhCache I have to go and change the setting by portion of this delta for every region!

Moreover, one installation might have higher usage of objects of type X whereas another installation might prefer higher churn of objects of type Y. We have dozens of installations and each installation would have hundreds of different caches. For this, we would have to hire bunch of people just doing nothing but monitoring cache patterns and tweaking the settings!

I was expecting CacheManager to have some sort of a global cache capacity setting and each internal cache would fight for more capacity, depending on entry usage. However the only way I found to set the cache capacity is via CacheConfiguration which is many-to-one against CacheManager.

So far the only option I can see is to try to force the Hibernate to use one global cache for all the entities. Does anybody know how to do that? Are there any other, better, solutions for my scenario?

解决方案

You can try having one single cache and adding decorators around it. The decorators can have names matching your region names so that hibernate can use those caches but those decorators would be using the same cache underneath. So theres only one cache config to manage. You can achieve this by implementing Custom cache decorators and set up the names of your decorated caches.

You can have ehcache.xml something like this:

<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>

The "com.xyz.util.CustomEhcacheDecoratorFactory" is a custom ehcache decorator factory class which is used to create the decorated ehcaches. You can use the "properties" attribute to set up the decorated ehcache in any way you want, here you only use a name property to configure the name of the new decorated ehcache. All other operations can be delegated to the underlying cache.

Providing one custom cache decorator that would work for this use-case here, it reuses the EhcacheDecoratorAdapter that comes in the ehcache jar and just overrides getName(). EhcacheDecoratorAdapter delegates all operations to an underlying ehcache which you pass in the constructor:


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;
            }
        };
    }
}

这篇关于指定全局EhCache容量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆