RailsのGemでそれを、やってくれるGem octopus (Git Hub - tchandy/octopus) があるので、これを使った実装は説明します。
インストール
gemのインストールは、Gemfileに以下を追加して、bundle installGemfile
# DB master slave振り分け
# https://github.com/tchandy/octopus
gem 'ar-octopus'
DBの接続先の設定
接続先の設定は、config/shards.ymlに行って行きます。公式のConfigファイルの設定に関するWikiはこちら。
全クエリの振り分け
更新のクエリは、マスターDB、参照のクエリはスレーブDBと全てのクエリに対して設定を行う場合は、下記。octopus:
replicated: true
environments:
- development
- staging
- production
development:
development_slave:
database: development_slave_db
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
staging:
staging_slave1:
database: staging_slave_db
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
production:
production_slave1:
database: production_slave1
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
production_slave2:
database: production_slave2
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
モデル毎の振り分け
モデル毎に、マスター、スレーブを使うかを決める場合は、こちら。fully_replicated: false を指定する。
octopus:
replicated: true
fully_replicated: false
environments:
- development
- staging
- production
development:
development_slave1:
database: development_slave_db
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
staging:
staging_slave1:
database: staging_slave_db
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
production:
production_slave1:
database: production_slave1
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
production_slave2:
database: production_slave2
adapter: postgresql
encoding: utf8
pool: 5
username: postgres
password: password
port: 5432
host: localhost
timeout: 5000
config/shards.ymlの他に、modeleから、replicated_model() メソッドを呼び出します。#This class is replicated, writes to master and reads to slave.
class Cat < ActiveRecord::Base
replicated_model()
end
接続の確認
上記まで、設定が完了していれば、rails c でCat.find(1)
とすれば、 下記のような、ログがとれるはずです。[Shard: development_slave1] Cat Load (0.4ms) SELECT "cats".* FROM "cats" WHERE "cats"."id" = $1 LIMIT 1 [["id", 1]]
直接DBを選択する場合
usingメソッドを呼び出します。マスターに投げる場合
Cat.using(:master).find(1)
スレーブに投げる場合
Cat.using(:development_slave1).find(1)
または、ブロックを使って。Octopus.using(:development_slave1) do
Cat.count
end
テスト環境の構築
テスト環境にもマスターDB、スレーブDBを作るのが環境的にはベストかもしれませんが、状況によって作れないこともあると思うので、そんな時は、読み取り専用のユーザーを作るの楽かと思います。
読み取り専用ユーザーの作成
postgresでの読み取り専用ロールの作り方は以下CREATE ROLE read_only_user LOGIN REPLICATION PASSWORD 'password';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only_user;
shards.ymlの設定変更
下記のように、databaseをマスターDBに向けて、usernameをread_only_userに変更すれば、OKです。octopus:
replicated: true
fully_replicated: false
environments:
- development
- staging
- production
development:
development_slave:
database: development_master_db
adapter: postgresql
encoding: utf8
pool: 5
username: read_only_user
password: password
port: 5432
host: localhost
timeout: 5000
障害発生時の対応
もし、マスターDBに以上が発生した場合などに、取り合えず、振り分け処理を停止したい時は - production をコメントアウトするのが有効かと思います。octopus:
replicated: true
fully_replicated: false
environments:
# - development
# - staging
# - production
development:
development_slave:
最低限、productionのみコメントにすれば、OKかと思います。 また、開発環境やステージング環境で、レプリケーション不要なんて時もコメントアウトしておけば、振り分け処理はおこなわれません。
0 件のコメント:
コメントを投稿