Hibernate L2 cache Strategy
Many people have little understanding of L2 cache, or is erroneous understanding, I have always wanted to write an article on the L2 cache to hibernate, today finally could not.
I mainly from the experience of hibernate2.1 version of the basic tenets of 3.0,3.1 and is the same, please forgive me incorrigibly obstinate.
Hibernate the session provided a cache, each session, with a load twice id, not sent to the two sql database, but the closed session, a failure on the cache.
SessionFactory level two cache is the global cache, which can be used under different cache class libraries, such as ehcache, oscache, the need for hibernate.cache.provider_class, we here to ehcache in 2.1 is hibernate.cache. If provider_class = net.sf.hibernate.cache.EhCacheProvider cache for use with hibernate.cache.use_query_cache = true
Cache can be as simple a Map, through key inside to find value in the cache.
Class Cache
For a record, which is a PO, it is in accordance with the ID come, the key is to cache ID, value is POJO. Whether list, load or iterate, as long as read out an object will be filled cache. But list will not use cache, and iterate from the database will first select id out, and then one of the id id a load, if there are in the cache, the cache on the admission, if not go to the database load. Assumption that the reader cache, the need for:
<cache Usage="read-write"/>
If you use the L2 cache is ehcache achieve it, need to configure ehcache.xml
<cache Name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
Which is not eternal cache that never overtime, timeToLiveSeconds each element is the cache (in this case is a POJO) overtime time, and if eternal = "false", more than the designated time, and this element has been removed the. TimeToIdleSeconds is Fabao, is optional. When the cache inside to put more than 500 elements, if overflowToDisk = "true", will be part of the cache data stored in the temporary files on your hard disk inside.
Each class must need this cache configuration. If you do not have distribution, hibernate in the warning when you start, then use the defaultCache configuration, a number of this class will be sharing a configuration.
When a revised ID through hibernate, hibernate know, then remove the cache.
So you may want to, the same conditions for the first time to list, the second re-iterate, you can use the cache to. In fact, it is very difficult, because you can not judge what time is the first time, and the conditions of each enquiry is not the same as usual, if there are 100 database records, id from 1 to 100, the first time a list of id of the former 50, the second time it iterate about the id, 30-70, then 30-50 from the cache from the inside, from 51 to 70 from the database, sent a total of +20 sql. So I always think that iterate what is not, there will always be the question of N + 1.
(Off-topic: the allegation that large-scale use for the results list will be set into memory, and very slow, and only select id iterate better, but we must always tabbed for large-scale investigation, no one really the whole result set installed in, if a 20, then iterate the need to implement a total of 21 sentences, although the list has selected a number of fields, than iterate first select id statement slower, but only a statement, not into the results will be set according to hibernate Database optimization dialects, such as the use mysql limit, or the overall list appears to be faster.)
If you want to list the results of inquiries or iterate cache, the cache will be used for
Enquiries cache
First need to configure hibernate.cache.use_query_cache = true
If ehcache, configuration ehcache.xml, pay attention to the future not net.sf hibernate3.0 packages were:
<Cache name = "net.sf.hibernate.cache.StandardQueryCache"
MaxElementsInMemory = "50" eternal = "false" timeToIdleSeconds = "3600"
TimeToLiveSeconds = "7200" overflowToDisk = "true" />
<Cache name = "net.sf.hibernate.cache.UpdateTimestampsCache"
MaxElementsInMemory = "5000" eternal = "true" overflowToDisk = "true" />
Then
Query.setCacheable (true); / / cache for activation
Query.setCacheRegion ( "myCacheRegion ");// designated to be used cacheRegion, optional second line designated to be used cacheRegion myCacheRegion is that you can do to each for a separate cache configuration, use to do this setCacheRegion specified the need to configure it ehcache.xml inside:
<cache Name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
If omitted the second line, set up cacheRegion, then will be used for the above-mentioned standard cache configuration, namely: net.sf.hibernate.cache.StandardQueryCache
For enquiries cache, the cache is based on the key hql generated sql, coupled with the parameters, such as paging information (log output can be seen, but its output is not very readable, best to check it out Code).
For example hql:
From Cat c where c.name like?
Sql generated along the following lines:
Select * from cat c where c.name like?
Parameter is the "tiger%," then cache enquiries about the key * * this is the string (I am writing from memory, and is not accurate, but also read it understand):
Select * from cat c where c.name like?, Parameter: tiger%
Thus, the same guarantee for the same parameters under the conditions with the same key.
Cache now to talk about the value, if the list is the way, here is not value the whole result set, but a string of enquiries from the ID. In other words, whether or iterate list method, for the first time, their very way for the way they usually are the same, the implementation of a list sql, iterate the implementation of N + 1, the extra acts is that they fill the cache. But to the same conditions for the second time, and iterate all acts the same way, according to the key to the cache found inside the cache value, value is a string id, and then to the class to a cache inside of a load up. This is done to save memory.
Can be seen, the cache need for the open-related class cache. Iterate list and the first implementation of the method, both are filled for cache and cache filled class.
There is also a very easy to overlook the important issues, that is open for the future cache, even list also may encounter 1 + N question! The same conditions when the first list, because not for the cache, regardless of the existence of class data cache, always sent a statement to the database sql access to all data, and then filled class for cache and cache. But the second performance when the issue comes, if your class cache overtime relatively short time, now have overtime class cache, but also for cache, then list approach in the acquisition after the string id , will be a database to a load! Therefore, the cache of overtime class time must not be shorter than the cache settings for overtime time! If it is set up Fabao time, ensure that class cache Fabao time for the cache than the survival time. There are also other circumstances, such as class evict cache was mandatory procedures, the situation on your own attention.
Also, if hql enquiries includes select words, the cache inside for the entire value is the result set.
When hibernate update the database when it knows how to update the cache enquiries?
Hibernate in a local preserve each table the final update time, but actually it is on top net.sf.hibernate.cache.UpdateTimestampsCache designated by the cache configuration inside.
When updated through hibernate, hibernate will know what impact the updated table. It then updates these tables last updated. Each cache has a time and this cache generated by the table, when hibernate for the existence of a cache, if there cache, it also wants to remove the cache and this time generated by the query cache table, and then to find these tables last updated, if there is a time table to generate updated this, the cache is invalid.
Can be seen, as long as updated a table, then all involved to the table enquiries on the failure of the cache, the cache hit rate enquiries may be relatively low.
Tags: hibernate, java cache






