I'm using Rails(3.2)+PostgresSQL(9.4) in my project. I have a continuously growing database.
I won't describe all the 70 tables and the large amount of partition for each of them so here is a very simplified structure:
- One table (users) contains user accounts
- One other table (bills) contains bills created by users (bills belongs_to users)
- The bills table is partitionned (one partition per user)
I use a multi-master replication (all datas, including partitions are replicated with PostgresSQL-BDR). To avoid conflits as much as possible I would implement a rule like "We have N servers, you are logged with id M : so you can update bills on server M % N". It's not an ultimate rule but it's sufficient for me.
My problem is I don't really know how to implement this rule to my application.
I searched and found this link and I implemented is but I don't like this solution. My implementation :
class ApplicationController < ActionController::Base
around_filter :select_connection
def select_connection
srv_selected = current_user.id % NB_OF_SERVERS
spec = ActiveRecord::Base.configurations[Rails.env + '_' + srv_selected]
ActiveRecord::Base.establish_connection(spec)
yield
end
end
And database.yml :
development: &development
adapter: postgresql
encoding: unicode
database: dbname
port: 5432
# etc...
development_1:
<<: *development
host: 127.0.0.1
development_2:
<<: *development
host: 172.17.0.2
# And so on ...
It works in developement but I really don't like that, the advantage of connection pool is lost (because it is recreated at each 'establish_connection' call I think) and I don't know what happens on multi-threaded server.
Do you know a better solution ? Maybe a kind of external connection pool (kind of pgpool like) ? But I don't know how to tell this 'proxy' which user have sent the request.
I hope my explanation is clear.
Thank you !