What's the point of living if you can't love or hate?
New JBoss Cache based Hibernate Second Level Cache provider
Posted by Galder Zamarreño on Sep 22, 2008 • (35) •
I’m really pleased to announce the 1.0.0.GA release of a new JBoss Cache 1.4 series-based implementation of Hibernate‘s 3.2 Second Level Cache provider SPI. The Second Level Cache is a Hibernate feature that allows entities, collections and queries to be cached in memory beyond the scope of a transaction, reducing the number of trips to the database. Hibernate provides an SPI for second level cache implementations; the JBoss Cache-based implementation is primarily used in clustered applications where there is a need to maintain cache consistency around the cluster.
Over the past year, Brian Stansberry, lead of JBoss AS Clustering, has been working hard first, improving the JBoss Cache-based EJB3 Entity Second Level Cache for the AS/EAP 4.2/4.3 series and secondly, writing the JBoss Cache 2.x series-based implementation of the Hibernate 3.3 Second Level Cache which will be used in AS/EAP 5.x. Along the way, with the help of Steve Ebersole, lead of Hibernate, Brian has acquired a lot of expertise in this area as shown by the “Using JBoss Cache 2 as a Hibernate Second Level Cache” guide belonging to the Hibernate 3.3 series (Note: Readers interested in this blog entry should focus their attention on the “Chapter 2 – Core Concepts” to understand the interaction between Hibernate and JBoss Cache. The rest of the guide focuses on the Hibernate 3.3 and JBoss Cache 2.x integration, and this is of little interest to EAP or AS 4.x users as these Hibernate and JBoss Cache versions are more advanced that the ones supported in the EAP/AS versions mentioned).
JBoss Portal has been a consumer of the Hibernate Second Level Cache for quite a while now but unfortunately, it hasn’t been benefiting from the work done by Brian for a couple of reasons. First, JBoss Portal is still based in Hibernate 3.2, same as AS/EAP 4.2/4.3 and secondly, the improvements done to the EJB3 Entity Second Level Cache for AS/EAP 4.2/4.3 lived within the ejb3 project in AS/EAP and therefore, were not readily usable to other projects. This is not the case any more though.
A few weeks ago, Prabhat Jha, a Senior Engineer within JBoss division at Red Hat, was doing some scalability testing for JBoss Portal in a clustered environment but he was facing some issues as you can see from this forum entry. Brian believed that JBoss Portal could benefit from the work done to improve the Hibernate – JBoss Cache integration for EJB3 Entity Second Level Cache but he was quite busy working on AS 5, so I pinged him and volunteered to help with such task.
Essentially, I took the EJB3 Entity Second Level Cache integration code, put it in a separate project and enhanced it with lessons learned by Brian during the development of the JBoss Cache-based implementation of the Hibernate 3.3 Second Level Cache. The end result is a brand new JBoss Cache-based Hibernate Second Level Cache Provider that performs and scales much better than any previous Hibernate 3.2/JBoss Cache 1.4 Second Level Cache providers by analysing what Hibernate is trying to do and using that knowledge to eliminate all but required cluster message traffic. By doing this, the lock contention and potential deadlocks arising from synchronous communication (a requirement due to the need to keep entity data in synch across different nodes) are vastly reduced.
For example, amongst the enhancements, an option called hibernate.treecache.local.puts.only, whose default value is true, has been added that makes sure any put calls on the Second Level Cache as a result of a read operation from the database are done locally which means that data read from database is not replicated to other nodes. However, if put calls on the JBoss Cache Second Level Cache instance are as a result of an update of the data in the database, the new cache provider does replicate them. The effect is intra-cluster messaging traffic is greatly reduced, and each node in the cluster only caches data being used on that node. But if data is modified on any node, all nodes are made aware of the change, ensuring stale data isn’t left in a cache.
So, how do you integrate this new cache provider into your system?
Lastly, configure any of the following optional properties if required:
hibernate.cache.region_prefix – A prefix to use for second-level cache region names. This is a very useful option when trying to segregate (quite often isolated) deployments in the Second Level Cache. Each isolated deployment would use a different region prefix.
hibernate.cache.use_query_cache – Boolean property that enables/disables query cache. This option is only recommended if the same queries, with the same parameters, are used over and over again. Please note that if query cache is enabled, JBoss Cache instance must be configured with REPL_SYNC cache mode. Otherwise, if query cache disabled, which is default behaviour, it is recommended that JBoss Cache instance is configured with INVALIDATION_SYNC cache mode. When cache data is updated, invalidation provides much better performance than replication because other cluster nodes only need to be notified that data is invalid rather than having to serialize the updated data and send it over to them. A full detailed explanation of this can be found in “Using JBoss Cache 2 as a Hibernate Second Level Cache” guide for Hibernate 3.3 and JBoss Cache 2.x.
hibernate.treecache.querycache.local.writes.only – This is a similar boolean option to local puts only except that it controls the behaviour of the put operations in the query cache region. It’s enabled by default when query cache is also enabled.