繁体   English   中英

EhCache Hibernate二级缓存maxBytesLocalHeap缓慢

[英]EhCache Hibernate 2nd level cache maxBytesLocalHeap slow

我在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注释来限制图形的行走,但我不确定如何解决这个问题:

  • 我是否必须忽略双向关联的一方以避免循环?
  • 我是否必须明确忽略我的域模型类的瞬态成员?
  • 一般来说,将EhCache与Hibernate一起使用时使用maxBytesLocalHeap是否明智,或者我应该选择maxEntriesLocalHeap ,因为Hibernate maxEntriesLocalHeap为每个实体保留一个单独的缓存区域?

[更新] :我发现,Hibernate不会缓存瞬态成员(请参阅Hibernate:是否可以在二级缓存中保存瞬态字段? ),因此无论如何都不应该将它们视为ehcache。 正确?

简短的回答

事实证明我遇到的问题是在我的模型中使用Joda-Time实例的结果(我使用Jadira的UserType库来映射Joda类型)。

Joda类型保留了各种内部引用(包括对时间顺序信息的引用,从而产生巨大的对象图),Ehcache的SizeOfEngine这些引用,导致我的原始警告。

我发现如何配置SizeOfEngine引擎以排除这些引用没有干净的方法,但是我想再一个更简洁的方法是强制Hibernate只将相关信息放到第二级缓存中(我的时间实例) LocalDateTimes情况)。

更新

Jadira在实现自定义类型时做出了糟糕的选择:请在此处查看我的答案

更多细节

这是我发现的关于我的OP(使用Hibernate 4.2.15.Final,EhCache 2.6.9和UserType 3.2.0.GA):

首先,我对Hibernate如何在其二级缓存中存储实体产生了误解。 在阅读Lorimer关于真正理解二级和查询缓存的博客文章后,很多事情对我来说更有意义:

  • 您不必担心双向关联(或者关于此问题的循环图),因为Hibernate只会将关联的ID放入缓存中。 即使它将整个实体的引用放入缓存中 - 它不会 - EhCache的SizeOf引擎将跟踪已访问过的图形中的对象,并且不会对它们进行两次调整。
  • 同样,您不必担心瞬态字段,因为Hibernate不会将它们放入缓存中
  • 理论上,使用maxBytesLocalHeap配置不应该有任何问题。 当您使用EhCache的SizeOf引擎未正确测量的自定义用户类型时,会出现问题。

我知道这是一个老问题。 但它可能对某些人有用。 我有同样的警告。 我花了很多时间来解决这个问题。 在我的例子中,EhCache不会忽略所有的hibernate代理类。 我的实体有一些具有惰性关联的字段,在测量大小期间,EhCache遍历整个休眠图。

最后我找到了这个页面并解决了它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM