EhCache休眠2级缓存maxBytesLocalHeap慢
在我的Spring驱动的应用程序中,我使用Hibernate(4.2.15.Final)和EhCache(2.6.9)作为第二级缓存,在标准的持久层中进行了设置。
一切正常。但是,将条目放入第二级缓存有时会花费一些时间。
我已经在一个显式ehcache.xml
文件中配置了域模型类的缓存(我没有配置默认缓存):
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
name="hibernate"
updateCheck="false"
monitoring="autodetect"
dynamicConfig="false"
maxBytesLocalHeap="300M"
maxBytesLocalDisk="500M">
<cache
name="org.mycorp.model.MyEntity"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
maxBytesLocalHeap="5M" />
...
</ehcache>
在持久性上下文启动时,我收到以下INFO消息记录:
DefaultSizeOfEngine | using Agent sizeof engine
以及执行期间的以下警告
ObjectGraphWalker | The configured limit of 1,000 object references was reached while attempting to calculate the size of the object graph. Severe performance degradation could occur if the sizing operation continues. [...]
AFAIK ObjectGraphWalker
必须调整放入缓存的实体的大小,因为我使用配置了单个缓存区域maxBytesLocalHeap
。
我的领域模型非常复杂,我知道可以通过@IgnoreSizeOf
注释限制图表的移动,但是我不确定如何解决该问题:
- 我是否必须忽略双向关联的一侧以避免循环?
- 我是否必须显式忽略域模型类的临时成员?
- 总的来说,
maxBytesLocalHeap
将EhCache与Hibernate一起使用是明智的选择还是我应该接受maxEntriesLocalHeap
,因为Hibernate 仍在为每个实体保留一个单独的缓存区域?
:我发现,Hibernate不会缓存临时成员,所以无论如何ehcache都不应考虑它们。正确?
回答:
原来,我遇到的问题是由于在模型中使用了Joda-
Time实例(我使用Jadira的UserType库来映射Joda类型)。
Joda类型保留了各种内部引用(包括对导致年代久远的对象图的年代信息的引用),而Ehcache遍历SizeOfEngine
这些引用导致了我的原始警告。
我没有找到一种干净的方法来配置SizeOfEngine引擎以排除这些引用,但是再一次,我猜想一种更干净的方法是强制Hibernate首先仅将相关信息放入第二级缓存(在我的时间实例中的情况LocalDateTimes
)。
这是我关于OP的发现(使用Hibernate 4.2.15.Final,EhCache 2.6.9和UserType 3.2.0.GA):
首先,我对Hibernate如何在第二级缓存中存储实体存有误解。阅读Lorimer关于真正了解二级缓存和查询缓存的博客条目后,很多事情对我来说更有意义:
- 您不必担心双向关联(或与此相关的循环图),因为Hibernate只会将关联的ID放入缓存中。即使将对整个实体的引用放入缓存中(但不是),EhCache的SizeOf Engine也会跟踪图中已访问过的对象,并且不会对它们进行两次大小调整。
- 同样,您不必担心瞬态字段,因为Hibernate不会将它们放入缓存中
- 从理论上讲,配置应该没有任何问题
maxBytesLocalHeap
。当前,当您使用EhCache的SizeOf引擎无法正确衡量的自定义用户类型时,会出现问题。
以上是 EhCache休眠2级缓存maxBytesLocalHeap慢 的全部内容, 来源链接: utcz.com/qa/411068.html