В связи с поднявшимся шумом вокруг масштабируемости социального сервиса Twitter, написанного на Ruby on Rails, мне становится довольно сложно игнорировать эту тему. Фактически, проблема касается любого Rails-разработчика, трудящегося (или планирующего трудиться) на сервисами с большой нагрузкой. Разработчики Twitter, например, явно не ожидали, что в столь короткий срок требования к производительности их детища вырастут до 11 тысяч запросов в секунду (в голове не укладывается даже). Такие стрессы, конечно, не предусмотришь заранее, но заранее знать как с ними бороться - надо.
Собственно, одним из элементов стратеги увеличения производительности приложения надо назвать масштабирование системы хранения данных. Частным случаем такого масштабирования можно считать разделение данных на кластеры, хранящиеся в разных базах на разных серверах. Для реализации данного подхода буквально вчера ребята из RevolutionHealth анонсировали специальный плагин к ActiveRecord под названием ActsAsPartitionable. Пример использования:
Модель
class SomeModel < ActiveRecord::Base
# use the read_only database from the database.yml
acts_as_partitionable :name => "partition_1",
:access => :readonly,
:db_config => :read_only
# use the default database for partition_2
acts_as_partitionable :name => "partition_2"
# use the a specific w/r database for partition_3
acts_as_partitionable :name => "partition_3",
:db_config => :some_model_partition
# Specify the database configuration from a hash
acts_as_partitionable :access => :readonly,
:db_config => {
:adapter => "mysql",
:database => "partionable_db_test",
:username => "root", :password => "",
:host => "localhost"
}
end
Конфигурация БД в database.yml
dbs:
database: master_db
host: master-host
read_only:
database: slave_db
host: slave-host
some_model_partition:
database: slave_db_2
host: slave-host
Использование в коде
r = SomeModel.readonly.find(:first) # executes against the read_only db - slave_db
r.field = 'value'
r.save! # raises ActiveRecord::ReadOnlyRecord
r.readonly? # true
t = SomeModel.partition_3.find(:first) # executes against slave_db_2
t.field = 'some value'
t.save! # success to partition_3
Официальная страница плагина: http://rubyforge.org/projects/actsaspartition
У меня, к сожалению, пока нет проектов, на которых можно было бы протестировать данный плагин. Если кто-то попробует его на живом приложении - я буду рад услышать ваши отзывы.