DOVEty 2009-03-30
hibernate 的二级缓存的使用一定是一个难题,有无数的文章见意不要使用hibernate的二级缓存,因为他会照成一些风险。然而,如果hibernate不使用二级缓存,它的性能是比较的低下的,说难听一点这时的他就是一个高级一点的代码生成器。
使用二级缓存有风险,它主要的风险有以下两点(可能还有很多,但我觉得这两个比较容易出问题)
1.容易产生脏数据。
2.配置不好,命中率低会造成资源的浪费,搞不好,还会把应用给绷了。
在使用时我们要怎么样,才能避开这个问题呢。
第一个风险,可以通过,设置适当的缓存时间和使用hibernate内置的乐观锁来避免。关于,缓存时间长短的判断的确是一个难题,设长了,脏数据的机率大增,如果设短了,命中率会跟着下降。这主要是看,应用对脏数据的忍赖力了,而且一个应用可能每一个模块也不一样。
第二个风险,我们可以我以下的步骤来减小风险在设计表的时候,找出那些不变的数据,直接使用hibernate的只读缓存。对那些常用,但不常变的数据(如基础数据)可以设置一下,可写缓存。
写一段程序,在clpm项目中加入hibernate的性能监测,监测在系统内真实的hibernate使用情况。也可以事先分析选择一些没有并发问题,而且用量大的数据,配置二级缓存和本义缓存。
能过hibernate的监测数据,选择一些被load的次数多的数据,使用二级缓存。选择一些被用HQL查询次数多的查询,并分析他是否会容易出现并发问题,为这些数据加入查询缓存,并合理的设置一个缓存的过期时间。
反复的进行监测,查看监测数据,去除那些命中率低和级存的数据多命中次数少的的二级缓存查询缓存,尽量找到一个最佳的配置。
<object class="java.util.HashMap">
<void method="put">
<string>getUpdateCount</string>
<long>0</long>
</void>
<void method="put">
<string>getLoadCount</string>
<long>73</long>
</void>
<void method="put">
<string>getFetchCount</string>
<long>74</long>
</void>
<void method="put">
<string>getInsertCount</string>
<long>0</long>
</void>
<void method="put">
<string>getDeleteCount</string>
<long>0</long>
</void>
<void method="put">
<string>entityName</string>
<string>org.CommonBo</string>
</void>
</object><object class="java.util.HashMap">
<void method="put">
<string>getSizeInMemory</string>
<long>0</long>
</void>
<void method="put">
<string>regionName</string>
<string>org.CommonBO</string>
</void>
<void method="put">
<string>getElementCountOnDisk</string>
<long>0</long>
</void>
<void method="put">
<string>getElementCountInMemory</string>
<long>0</long>
</void>
<void method="put">
<string>getHitCount</string>
<long>0</long>
</void>
<void method="put">
<string>getMissCount</string>
<long>0</long>
</void>
<void method="put">
<string>getPutCount</string>
<long>0</long>
</void>
</object> <object class="java.util.ArrayList">
<void method="add">
<object class="java.util.HashMap">
<void method="put">
<string>getExecutionMaxTime</string>
<long>1125</long>
</void>
<void method="put">
<string>getExecutionCount</string>
<long>1</long>
</void>
<void method="put">
<string>getExecutionRowCount</string>
<long>1</long>
</void>
<void method="put">
<string>getCacheMissCount</string>
<long>0</long>
</void>
<void method="put">
<string>getExecutionMinTime</string>
<long>0</long>
</void>
<void method="put">
<string>getExecutionAvgTime</string>
<long>1125</long>
</void>
<void method="put">
<string>getCachePutCount</string>
<long>0</long>
</void>
<void method="put">
<string>getCacheHitCount</string>
<long>0</long>
</void>
<void method="put">
<string>queryhql</string>
<string>from org.CommonBO as c</string>
</void>
</object>