Thursday, March 13, 2008

Hibernate and Memcached

As I mentioned at the end of my last post, Cache Everything, I am working on building a library to use memcached from Hibernate as a second level cache. That project is hibernate-memcached and its in it's infancy over at googlecode.

The Hibernate second level cache is used to cache items between session invocations. Hibernate always uses it's session as a first level cache, but if you want to avoid database hits between sessions you need a second level cache. If you want these caches to stay in synch between several instances of your application, you need a distributed second level cache.

Memcached is a fantastically fast distributed cache, so why not use that? Once I build a jar of the hibernate-memcached project you'll be able to include it in your application and tell Hibernate to use it. Telling Hibernate to use it means adding the cache_provider property to your hibernate.cfg.xml, or your Spring LocalSessionFactoryBean if you're using that. The hiberante.cfg.xml looks like this...

<hibernate-configuration>
<session-factory>
<property name="hibernate.cache.provider_class">com.googlecode.hibernate.memcached.MemcachedCacheProvider</property>
<mapping class="com.yadda.yadda.Something"/>
</session-factory>
</hibernate-configuration>


Then, in your mappings you tell Hibernate that you want instances of your persistent objects to be cached, or collections from relation ships to be cached. Once Hibernate knows what you want cached you can watch it pump stuff into memcached, which is good clean geeky fun. Fire up memcahed (on windows or linux) using the -vv command line option to make it run "very verbose". You can see it storing and responding for each operation taken.

You can play with the code straight out of subversion at google code. It will actually work and cache stuff, but it is currently hardcoded to look only at localhost:11211 for a memcached instance. I'll get around to making it configurable. To build the code you'll need Maven2. I highly recommend using Don Brown's no-suck port of maven2 actually.

More to come...

10 comments:

Vinay said...

Really cool articles bud. Can you elaborate a bit on the advantages of using MemCached over other commercial products (other than the obvious thing that it is free!! :) ). Does MemCached work on large no of distributed nodes?

Ray Krueger said...

The previous artcle, Cache Everything, talks a little more about memcached specifically.

Memcached can scale across a huge number of nodes, I can't give you any hard numbers only generalizations :)

As for comparing it to other systems, have a look at the Coherence configuration mechanisms vs. the memcached options. Coherence has it's uses that's for sure, some of them are quite different than what memcached goes after. I think this should all be the subject of another post...

Oh, and memcached isn't just free, it's open source :) If you think there's a bug; go look. If you think you can improve it; have at it. Try that with the "enterprisey" systems out there. :)

Anonymous said...

I'm kind of confused how it works if you have slave/master situation, due to a legacy env i have 2 instances of spring hibernate services, one connected to master for update and one to slave for read. so i understand that caching goes to the master configuration but isn't read the place that i really need it?

Ray Krueger said...

You update from one database and read from another but it's the same data?

Anonymous said...

sorry, the other way around same data, update to the master and read from the slaves

Anonymous said...

ok - i left 2 comments. the first one was inaccurate and I tried to correct it with second comment but i see the first one never got posted so here is the situation

its the same data, I read from the slave and write to the master

Ray Krueger said...

And you use Hibernate for this?

Anonymous said...

yes, i have configured 2 data sources one for master and other for slaves

a green spot said...

I appreciate if somebody helps me with this problem. After I configured memcached and hibernate, I can see in the memcaced log that the object is being returned successfully - but at the same time I can see a log that hibernate is issuing a select statement to get the object from the database.

to test this, I am manually updating the database via mysql client and i CAN see the updated record when I get the object from hibernate. so this kind of proves the fact about my concern that Hibernate after gets the data from the cache it goes a head and gets it from the database anyways! any idea?

Ray Krueger said...

Please post your questions to the hibernate-memcached google group.

http://groups.google.com/group/hibernate-memcached