... mostly about Ruby and Rails...

Freitag, 15. Juni 2007

Rails Database Loadbalancing with DynamicDatabaseChanger Example

Okay, as requested by DrNic, I will give a quick example on how to loadbalance a Rails application to a clustered database with my DynamicDatabaseChanger plugin.

The assumptions for this to work is that you can connect to whatever database server you want to for reading and for writing. All instances have the same database.

... and of course you should have installed the plugin from svn://rubyforge.org/var/svn/ddcplugin

So, here we go. First, we need to define all the additional DB instances that we could connect to in database.yml:


shared: &shared
adapter: mysql
encoding: utf8
username: rails
password: rails_password
database: app_production

production:
<<: *shared
host: db
production0:
<<: *shared
host: db1
production1:
<<: *shared
host: db2
production2:
<<: *shared
host: db3


As you can see, the standard production DB is located on host db, the additional ones on db[1-3]. The rest of the definitions is the same for all.

Next, we have to tell the plugin when to use what DB. We do this in environment.rb:


ActionController::Base.dynamic_database_change_guard=
Proc.new{ |request|
prodDBs = ActiveRecord::Base.configurations.keys.select
{|k| k.include? "production" }
prodDBs[rand(prodDBs.size)]
}

What happens here? This is the central decision point of the plugin. The implementation here simply fetches all affected DB definitions from database.yml and returns a random one.

That's all! It's just that simple.


What happens in the background? The plugin adds an around filter to the beginning of the ActionController processing. In this hook, the above function is called and depending on the result, the connection of ActiveRecord::Base is changed. From then on, the action is processed using the changed database connection. After finishing the request, the connection is reseted to the standard one.

I implemented this in my lab at home( the hard part was the database set up ;-) and it worked quite well.

More examples can be found in the README.

So, try it out for your self and tell me your results.

-alex

P.S. instead of using 4 different DB servers for testing this, it's possible to use 1 DB server with 4 different users and see in the DB log the different users connecting:


shared: &shared
adapter: mysql
encoding: utf8
database: app_production
host: db

production:
<<: *shared
username: rails
password: rails_password
production0:
<<: *shared
username: rails1
password: rails1_password
production1:
<<: *shared
username: rails2
password: rails2_password
production2:
<<: *shared
username: rails3
password: rails3_password

Keine Kommentare: