ReplidogはRailsでの複数DB接続をサポートするツールです。
- 複数マスタ・スレーブ(テーブル単位の分割)対応
- Read/Writeの自動振り分け
- Rails 3.2, 4,0, 4,1, 4.2, 5,0, 5.1
- マルチスレッド対応(pumaでも使える)
なぜつくったか
Rails 4.0以上で複数マスタ・スレーブでRead/Writeの自動振り分けをしたかったからです。
Rails 4.0以上で複数DBをサポートするライブラリとしては以下が有名です。
Octpusはどちらかというとシャーディングに特化したツールで、複数マスタ・スレーブをサポートしてません。一方SwitchPointは複数マスタ・スレーブを扱えますが、Read/Writeの自動振り分けに対応していません。
複数マスタ・スレーブとRead/Writeの自動振り分け両方をサポートしているライブラリとしてReplicatがありますが、試してみたところ複数マスタ・スレーブがうまく動かなかったのと、レプリケーションのやり方に難があったので断念しました。
ただReplicatの設定ファイルの書き方がよかったのと、ソースコードがシンプルでいじりやすそうだったのでReplicatを改良することにしました。当初は完成したらReplicatにプルリクエストをしようと思ってましたが、基本的なデータ構造をざっくり変更することになり使い方も変わったので、独自ライブラリとしてリリースすることにしました。名前はReplicatをもじってReplidogとしました。
インストール
gem install replidog
bundlerで使うならGemfileに
gem "replidog"
使い方
Replicatとほぼ同じです。
# app/models/recipe.rb
class Recipe < ActiveRecord::Base
establish_connection :production_recipe
end
# config/database.yml
production:
<<: *production
host: 192.168.24.1
replications:
slave1:
<<: *slave
host: 192.168.24.2
slave2:
<<: *slave
host: 192.168.24.3
slave3:
<<: *slave
host: 192.168.24.4
production_recipe:
<<: *production
host: 192.168.24.5
replications:
slave1:
<<: *slave
host: 192.168.24.6
slave2:
<<: *slave
host: 192.168.24.7
slave3:
<<: *slave
host: 192.168.24.8
replicatoins
の部分がスレーブ接続の設定です。
production
は従来通り自動的にActiveRecord::Baseのサブクラス全てで使われますが、もうひとつのマスタproduction_recipe
は明示的にestablish_connectoin
で宣言する必要があります。
モデルのDB接続メソッド呼び出し時にselect系のものはスレーブへ、それ以外はマスターへ自動的に振り分けられます。トランザクションの中ではselect系も含めて全てマスターに振り分けられます。
また自動振り分けせずに明示的にコネクションを切り替えることも可能です。詳しくはREADMEをご覧ください。
production_recipe
で複数のモデルを扱いたいときは抽象クラスをつくって継承させます。
# app/models/recipe_table.rb
class RecipeTable < ActiveRecord::Base
self.abstract_class = true
establish_connection :production_recipe
end
# app/models/recipe.rb
class Recipe < RecipeTable
end
コネクション運用・クエリキャッシュ
Replidogでは以下のARのメソッドを書き換えて全てのマスタ・スレーブ接続に対して実行するようにしています。そのため既存のRailsのmiddlewareやUnicorn等のAPPサーバーの設定を変更することなく導入できます。
clear_xxx_connections
- ActiveRecord::Base.clear_active_connections
- ActiveRecord::Base.clear_reloadable_connections
- ActiveRecord::Base.clear_all_connections
クエリキャッシュ
- ActiveRecord::Base.connection.enable_query_cache!
- ActiveRecord::Base.connection.disable_query_cache!
- ActiveRecord::Base.connection.clear_query_cache!
運用実績
Taptripというアプリのバックエンドで以下の組み合わせでの運用実績があります。
- Rails 3.2, 4.2
- Ruby 2.2
- Mysql 5.6