Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Fri Apr 13, 2012 9:53 am 
Newbie

Joined: Fri Apr 13, 2012 9:41 am
Posts: 3
Hi there,

has anybody heard of 'versioned' or 'timestamp-aware' L2 caches? This could enable transactional caching without the Terracotta infrastructure.

A colleague of mine implemented a versioned cache for entities that rarely change. But his cache is on top of Hibernate. Thus my question: Is there something similar available as L2 cache for Hibernate?

The idea of a versioned cache is quite easy: The application transactions use a timestamp-aware cache.

How does it work in detail? Let's say all entities of type MyGlobalVariable shall be cached. If any of these entities is changed, then a timestamp is increased somewhere else in the database. As soon the cache is requested the first time within the current user transaction, the timestamp is fetched from the database. If the timestamp is a new one, then a new empty internal cache is created for this timestamp. Then the cache delegates to the timestamp-specific internal cache. That's all.

Thanks,
rwoo


Top
 Profile  
 
 Post subject: Re: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Fri Apr 13, 2012 11:00 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 988
Quote:
As soon the cache is requested the first time within the current user transaction, the timestamp is fetched from the database.


Sorry, but this seems to me a very ugly implementation of a 2L-cache, because you are going to hit the database anyway.
Why don't you trust on well tested and widely used 2L-cache implementatios like EHCache or Infinispan ?


Top
 Profile  
 
 Post subject: Re: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Tue Apr 17, 2012 6:03 pm 
Newbie

Joined: Fri Apr 13, 2012 9:41 am
Posts: 3
Hi Pb00067,

Quote:
Sorry, but this seems to me a very ugly implementation of a 2L-cache, because you are going to hit the database anyway.

Yes, at first sight it looks like a bad idea but the aim of the versioned cache is not to avoid database access completely. Instead the aim is to substantially reduce the number of queries sent to the database and to reduce the amount of query results without making compromises in respect to the transactional behaviour of the application. This aim is accomplished with the versioned cache: The database server gets far less queries with the versioned cache than without the cache. And the transactional behaviour of the application is the same as without the cache. This is what we learnt in the years the cache has been used in our web applications.


Quote:
Why don't you trust on well tested and widely used 2L-cache implementations like EHCache or Infinispan?

I do trust on Ehcache, we already use Ehcache in other use cases and we like it very much. I don't know Infinispan.

Actually I hoped that Ehcache or another 2L-cache implementation would provide something like a versioned cache out-of-the-box. But I haven't found anything like that in the documentation of Ehcache. That is why I asked you here in the forum.

Regards
Rod

P.S.
A bit more background: We use Hibernate outside of an JEE application server, i.e. we use Tomcat+Spring+Hibernate. We are not really keen to introduce JTA. The cacheable data are maintained by a single web application and read by many other web applications.

P.P.S.
Pb00067, if you still consider the versioned cache a bad idea for a 2L-cache, please let me know your reasons. I am not very familiar with the inner workings and the configuration of the 2L-cache (read-write, nonstrict-read-write, read-only etc.) and the implications that result from them.


Top
 Profile  
 
 Post subject: Re: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Fri Apr 20, 2012 5:52 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 988
Quote:
Pb00067, if you still consider the versioned cache a bad idea for a 2L-cache, please let me know your reasons.


For me it it's not clear how your cache-implementation avoids database hits when you are performing queries.
Maybe you can explain that deeper?


Top
 Profile  
 
 Post subject: Re: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Mon Apr 30, 2012 8:59 am 
Newbie

Joined: Fri Apr 13, 2012 9:41 am
Posts: 3
Quote:
For me it's not clear how your cache-implementation avoids database hits when you are performing queries.
Maybe you can explain that deeper?



Gladly.

1. Does our versioned cache support query caching?

No.

2. Why not?

We don't need query caching for the abovementioned entities of type MyGlobalVariable. So we didn't care about query caching.

By the way, we use Ehcache L2-caching when querying other entity types. Our versioned cache and the Ehcache caches do not impede each other because they work on distinct sets of entities.

3. Could our versioned cache support query caching?

I think: Yes. But I have not thought about that before you asked, Pb00067.

The approach would be the same as used by the Ehcache query cache (a good explanation can be found on http://tech.puredanger.com/2009/07/10/h ... ery-cache/ ) apart from a small but important difference: The table-specific timestamps are not cached but saved in the database. The query cache and the entity cache would share the same table-specific timestamps. That's all.

Then the query cache would behave like the entity cache: If the table MyGlobalVariable is queried the first time within the current user transaction, the table-specific timestamp is fetched from the database. If the timestamp is a new one, then a new empty internal cache is created for this timestamp. Then the cache delegates to the timestamp-specific internal cache.

4. How would the versioned query cache work for queries that span over more than one table?

Example: If a query has to access the tables MyGlobalVariable1 and MyGlobalVariable2 the first time within the current user transaction then the timestamps for those two tables are fetched from the database. If there is already an internal cache for the combination of these two timestamps, then this internal cache is used. Otherwise a new internal cache is created and used.

Hint: Each timestamp is fetched not more than once per user transaction.

5. Summarizing: versioned cache and L2-cache - do they fit together?

For me it looks like.

If the term versioned cache sounds too unfamiliar, you may name it a snapshot cache because the cache holds effectively database snapshots.


And, Pb00067, you might be interested in the final bit as well:

6. Is there a way to avoid the database hits entirely or almost entirely?

Yes if you are able to announce changes in the database in advance (see details below). This should be possible for rarely changing entities.

Let me explain the approach in detail by an example:

Let's say the contents of table MyGlobalVariable are rarely changing, like 10 times a month but you don't know exactly when it happens.

-- Configuration --

First you configure five minutes as TTL (time-to-live) for the cache that belongs to the table MyGlobalVariable. By this configuration a property called DeactivateCachingAfterTime (something like "2012-12-31 11:59:59") specific to the table MyGlobalVariable is persisted somewhere in the database. This property is initially and most of the time null.

-- User perspective --

If a user wants to make changes to the table MyGlobalVariable, then the user must set the property DeactivateCachingAfterTime to a time at least five minutes (the configured TTL) in advance. After the DeactivateCachingAfterTime is reached the user is allowed to change the contents of the table MyGlobalVariable. As soon the user has finished his changes, he should set the property DeactivateCachingAfterTime to null again.

If the user is another system or the user wants to schedule his change (he does not want to wait five minutes in front of the application), then think about a cron job or something similar that makes the change automatically when the DeactivateCachingAfterTime is reached.

-- Cache implementation --

How is the versioned cached affected by the property DeactivateCachingAfterTime?

Before the timestamp is fetched from the database the cache checks when the most recent timestamp was fetched from the database. If this happened within the last five minutes (the configured TTL), then the most recent timestamp is used, i.e. the database is not queried (this is the optimization). Otherwise the timestamp and the property DeactivateCachingAfterTime are fetched from the database. If the fetched DeactivateCachingAfterTime is not null, then the versioned cache will fetch the timestamps for each user transaction as soon the DeactivateCachingAfterTime is reached, i.e. the optimization will be switched off. As soon the fetched expiration is null, the optimization is switched on again.

-- Caching efficiency --

As long the user changes the contents of the table (this may add up to an hour in each month) as long the timestamps are fetched from the database for each user transaction (what is a serious problem only if you have a million transactions in this hour). But for the rest of the time (the month minus the hour), the timestamps are fetched only once in five minutes (the configured TTL) whether you have to serve either one hundred or a million transactions, i.e. more than 99% of the cacheable database queries might not hit the database.

Regards
Rod


Top
 Profile  
 
 Post subject: Re: 'versioned' or 'timestamp-aware' L2 cache available?
PostPosted: Mon May 07, 2012 10:38 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 988
Hi Rod,

thank you for the detailed explanation.
Anyway I see no benefit in using your cache implementation, instead to use Hibernate standard 2L-caching (for example with EHCache)
Here some argumentation:
- Hibernate 2L-Caching provides caching for Entities, Collections and Queries
You say that also you implementation could support queries, but does your implementation also support caching of persistent collections ?

- If you use a cache access strategy >= READ_WRITE and configure EHCache in manner that your entity MyGlobalVariable is cached eternally,
and assuming that all inserts/deletes/updates to table MyGlobalVariable are always performed through Hibernate,
then once the cache is filled, hibernate never needs to reread records from table MyGlobalVariable again (for the lifetime of your SessionFactory).
This because, usually when you write a change on MyGlobalVariable to the database through hibernate,
then according cache entry get synchronized immediately, without need to fetch fresh record again from database.
Your implementation indeed seems to need to refresh it's cached data from time to time in order to avoid stale data.

- In your implementation, an user must announce content changes on table MyGlobalVariable.
With hibernate 2L-cache this is not required.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.