Brian Stansberry's Blog

October 8, 2009

Improvements to Clustered Caching of Frequently Inserted Entity Types

Filed under: Hibernate,JBoss — Brian Stansberry @ 10:07 pm

I made a very simple change today to Hibernate’s integration with JBoss Cache that should have big benefits. Hibernate integrates with JBoss Cache to allow second-level caching of entities, collections and query results in a clustered environment. I often advise people to be cautious about what types of entities they cache in a cluster. A clustered cache differs from a single node cache in that it needs to maintain consistency around the cluster. This means sending messages around the cluster when cache contents change. For entity types with a relatively high percentage of cache writes, the cost of these messages can outweigh the benefits of caching.

For entity caches, by default JBoss Cache is configured to send invalidation messages around the cluster when its contents change. Well, I realized that sending an invalidation message around the cluster when Hibernate has just inserted a newly created entity into the cache is just silly. The entity is brand new; there’s no way another node in the cluster could have a stale version of the entity that needs to be invalidated out of its local cache. Fortunately, the excellent RegionFactory SPI Steve Ebersole introduced in Hibernate 3.3 gives me all the contextual information I need to know that what’s being cached is a newly created entity. And JBoss Cache’s Option.setCacheModeLocal(true) API gives me the power to disable sending out the invalidation message when I put those newly created entities into JBC. Result: with the addition of a few lines of code I can remove these unnecessary messages.

What’s the benefit? Basically, a whole new category of entity types can now benefit from caching in a cluster. Types that may have a fairly high percentage of cache writes relative to reads, but where those writes represent a database INSERT, rather than an UPDATE. Imagine for example, a purchasing application, where user activity generates lots of Order and OrderLineItem entity inserts. Once those entities are created, they are unlikely to be changed, but in the course of a user’s interaction with the application there is a high enough likelihood that they will look at the order details again to make caching the entities worthwhile. Prior to today’s change, caching Order and OrderLineItem may not have been performant. Now, if reads of those entities are frequent enough to make caching them worthwhile in a non-clustered environment, it’s likely to be worthwhile in a cluster as well.

As always, load test your application with realistic usage scenarios before and after turning on caching of any entity type, collection or query result.

The JIRA for this change can be found in Hibernate’s JIRA at HHH-4484. The improved behavior will be available in the Hibernate Core 3.5 release.

Advertisements

5 Comments »

  1. Hello Brian,

    is your implementation just caching entities or also caching “relationships” (i.e. can you navigate from master-to-slaves entirely in cache or do you have to load the slave IDs from the DB)? If you do also cache the relationships, I imagine you’d still need to either update or invalidate those if you were to create a new entity.

    Cheers,

    sacha

    Comment by Sacha Labourey — October 9, 2009 @ 7:14 pm | Reply

  2. Hi Sacha,

    Good question.

    The 2nd level cache does allow users to cache relationships. Hibernate provides a “collection cache”, where it caches the primary keys of entities that are members of a collection field in another entity type.

    To very narrowly answer your question, the change I discussed in the blog post above does not affect how collection caching works. The Hibernate/JBoss Cache integration layer is unaware of any relationships between the data it is caching. It just implements an SPI and does what core Hibernate tells it to do. The SPI doesn’t provide enough information to allow the Hibernate/JBC integration ot have any knowledge of how different types of cached items are related to each other.

    Core Hibernate, however, of course has a lot of information about relationships, and it uses that information to invalidate collections out of the 2nd level cache when their contents change. How that works has some interesting subtleties though; interesting enough that I think they’re worthy of a separate blog post. So…

    https://bstansberry.wordpress.com/2009/10/09/collection-caching-in-the-hibernate-second-level-cache/

    Best regards,

    Brian

    Comment by Brian Stansberry — October 9, 2009 @ 5:45 pm | Reply

  3. BTW, Sacha, the part most specific to your question is at the bottom of the new blog post. Lots of configuration stuff to wade through first. šŸ™‚

    Comment by Brian Stansberry — October 9, 2009 @ 5:47 pm | Reply

  4. Thanks, that’s great Brian šŸ™‚

    Comment by Sacha Labourey — October 15, 2009 @ 1:18 am | Reply

  5. […] a follow up to something I blogged about a couple months ago: a simple change to the Hibernate Second Level Cache integration with JBoss […]

    Pingback by Clustering Features in JBoss Application Server 6.0.0.M1 « Brian Stansberry's Blog — December 2, 2009 @ 11:05 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: