Spring framework, Hibernate and MySQL Replication


Laterly we have our site grown to the stage that a single mysql server will not able to do the job anymore. That's something we realy like to see. The CPU usage had reached more then 90% at peak traffic time. MySQL even crashed a couple time when we were running an early version. 5.0.x. Don't remember what it was exactly. But when we upgrade to 5.0.24, it stopped crashing. It was also unacceptablely slow under the heavy loads. We need some heavy duty database solution.

I have read a couple articals about mysql cluster. So my first thought is cluster. But when we ask our hosting company to set up a MySQL cluster, they suggested replication instead. Sometimes you just could not judge things by their name. Have run into the word "replication" a couple times in the mysql ref book. I miss judged the replication function. My sql does not like some other databases, this replication is real-time replication.

To set up a master/slave replication system up is really a straight forward thing to do. I installed FC6 on my desktop. Enjoyed the new tool FC6 provided for xen vertiual machine. As others said, it's like using VMWare. A big improvement from FC5. Followed the mysql reference book, made it work after a couple tries. Xen is such a good thing to have. Doesn't have to be big, Xen is a perfect fit for this low cost testing environment.

So far, we had the database ready for testing. We had one more thing now quite figured out by the time. How does the app use this master/slave system. With the question, did a little search on google. Found the ReplicationDriver that is provided by MySQL Connecter/J is what we need.

Our application is a Sping+Hibernate J2ee web application. App is doing declarative transaction by using "org.springframework.transaction.interceptor.TransactionProxyFactoryBean". The connection pool we used is Apache DBCP. Rock solid connection pool. I like to have all things controlled and configured in one place. So had the driver changed in our sping applicationContext config, Ant build, deploy, and start my local environment. Everything was fine. I had my both mysql instances general logging on. Look at the log files, everything was what we expected. Reads and searchs were on slave. Updates were on master. We had a little concern about Spring. The mysql ref book's sample code explained the setReadOnly(). We were not sure what Spring is doing. Once we saw it's working. We had no more concerns.

The second day, it only took me a couple minutes to have the replication set up. The firewall gave us a small supprise. Did not take long to relise the port is not open. Had the app configuration change to the new master/slave servers. Restart our app, master mysql's cpu drop to 10%. Slaves are about 20%.

Although it's working, we had to do a trick for a small problem. Our connection pool seems only use the first slave server. So I fooled the app by giving it different ips for the same hostname. A group of our app servers are using one slave server, the other group is using the second. The ReplicationDriver is probably picking the first slave by default. Because it was said, the slave connection is sticky. It probably will not use other slaves unlease something bad happen. I am going to check it out when I have a chance.

Comments

Vlad said…
Hi Neil,

I am using a similar setup, but with iBatis instead of Hibernate.

The issue I have with DBCP and ReplicationDriver is the following.

ReplicationDriver creates two physical connections, one to the master and to slave. When one of the connection is lost (could be closed by MySQL after inactive timeout or MySQL was restarted), the stale connection stays in the pool. After that the application is getting stale connections from the pool and fails. The problem is well described here.

Have you experienced such a problem? If yes, how did you solve it.

Thank you in advance!

/Vlad
ZSA said…
Hi,

I have tried everything to get such setup working. I am using
Spring/Hibernate and applying TransactionProxyFactoryBean to the DAO but nothing is happening on the read-only database. Is it possible to get hold of some sample code/xml to make mine work. I have searched for over a week now and now there is a lot at stake.

Regards,
ZSA said…
I think I have resolved it.

I was missing the following from the properties in dataSource
Tags are ommited due to restrictions on this site.
props
prop key="autoReconnect"
true
prop key="roundRobinLoadBalance"
true

props
a green spot said…
anybody have used hibernate-memcached with this setup? I am thinking about using memcached as a caching layer on top of hibernate but I'm not sure about how it is going to behave since master gets the updates and supposedly expires the updated objects in the cache and slaves are returning from the cach

Popular posts from this blog

Exposed Domain Object implemented with Spring Aspect Transaction Control + AspectJ

the Art of Kindling a Light in the darkness of mere being