l'essentiel est invisible pour les yeux

Wednesday, March 08, 2006

ActiveRecord Cluster (複数データベースを扱うプラグイン)

Active Record Cluster

ttp://rakuto.nobody.jp/src/active_record_cluster.zip

直接リンクだと403になります。
右クリックでURLをコピーして直接URLバーに入力してください。

を作りました。

で、これは何かって言うと

DBコネクションをクラスタ単位で扱うためのプラグイン。
「DB一台じゃクエリ捌くの無理だろ」って時に使います。

だけど、ActiveRecordは複数DBを扱うのに向いていないんですよ。
というかRails作者のDavid自身が一つのDBでARを使うことを強くお勧めしています。

そのため内部では、クラス名をハッシュキーとスレッドIDをキーとしてコネクションアダプタ(ActiveRecord::ConnectionAdapter)をキャッシュしています。

ActiveRecord Clusterでは、クラスタ毎に
「更新系リクエストのためのコネクションアダプタ」
「参照系リクエストのためのコネクションアダプタ」
を同時に管理できるように、キャッシュ機構を設けました。

個人用途ではあまり意味無さげ。
社内ではSVNレポジトリ立てたんだけど、外部に公開できるサーバ持って無いので、
ダウンロードして手動で/path/to/rails-app/vendor/plugins以下に配置します。

---------
更新履歴
---------
2005/02/16
スケジューリングアルゴリズムモジュールを切り離し、
コネクションのキャッシュを一つのメソッドで一元管理するようにしてDRY(Don't repeat your self).

2005/02/17
○コネクションの冗長化を実装しました。
(参照系リクエストの場合にスレーブ障害が起きていて接続できない場合、スレーブを接続対象から切り離し他のスレーブに接続を試みる。全てのスレーブがダウンしている場合は、マスタに対して接続を試みる。)

○ClusterモジュールをMixinして拡張を行う方法に変更。
(以前はActiveRecord::Baseに特異クラスを定義していた。)

2005/03/07
○Active Record Clusterの#delete or #delete_all呼び出しの際にコネクションをマスタに付け替える実装を付け加えました。
○バグ修正

ソースコード: Active Record Cluster

READMEを引用
== Welcome to Active Record Cluster

Active Record Clusterは、Active Recordを拡張するプラグインです。
一つマスタと複数台のスレーブを一つのクラスタとして扱い、
クラスタに対してコネクションを獲得することが出来るように拡張しています。

設定したクラスタへのコネクションで更新系クエリは全てマスタに対して
獲得され、参照系のクエリはスレーブ間で分散されます。

スレーブ間での負荷分散のアルゴリズムは現在のところラウンドロビンスケジューリングのみをサポートしています。

冗長化機能について (参照系のリクエストのみ)
接続先のホストに障害が発生していて接続できない場合、他のスレーブに対して
障害が起きているホストをクラスタから切り離し、他のスレーブに対して接続を試みます。
もし、全てのスレーブがダウンしていた場合は、マスタに対してコネクションを確立します。

Author:: rakuto (http://rakuto.blogspot.com/)
Copyright 2006 rakuto (http://rakuto.blogspot.com/)
License:: MIT

== Getting start
1. 始めにclusters.ymlというファイルを編集する必要があります。このファイルにはDBのクラスタ情報を書いておきます。書けたら#{RAILS_ROOT}/config/clusters.ymlにデプロイでOKです.

2. 次にclusters.ymlのクラスタ設定ファイル中に設定したホスト情報の接続情報を#{RAILS_ROOT}/config/database.ymlに書きます。文法はRailsのdatabse.ymlと同じです。

3. 使用するApplicationController(デフォルトなら#{RAILS_ROOT}/app/application.rb)中にクラスタ情報の初期化命令をbefore_filter(ActionController::Filters::ClassMethods)のコールバックメソッドとして指定します。

class ApplicationController < ActionController::Base
before_filter :init_cluster

def init_cluster
ActiveRecord::Base.initialize_clusters
end
end

こんな感じです。

4. 後は、各モデルで接続先のクラスタを指定します。クラスタの指定にはspecify_clusterメソッドを使用します。

class Hoges < ActiveRecord::Base
specify_cluster :hoge_cluster01
end

ID等の条件で一つのテーブルを複数ホストに分割したい場合は、コールバックメソッドを定義する。コールバックメソッドでは、接続先のクラスタ名を返す。

class Hoges < ActiveRecord::Base
specify_cluster_condition :condition

def conditon
if self.id %lt; 1000000
'hoge_cluster01'
else
'hoge_cluster02'
end
end
end

ですがこの機能はまだテストしていません。
次のバージョンで動作するようにします。はい。


== config file format

1. clusters.yml
次のようなフォーマットになります。
スレーブは省略できますが、マスタは省略できません。(そんな構成はないので。)
ルートの要素は、#{RAILS_ENV}の値にしてください。
ここに書いたホストへの接続情報をdatabase.ymlに指定します。

production:
hoge_cluster01:
master: master-db001
slaves:
- slave-db001
- slave-db002
- slave-db003

2. database.yml
指定するスペックはRailsと同じです。

master-db001:
host: master-db001
user: david
database: transaction-db

5. TODO
ID等の条件による接続先クラスタの切り替え
UnitTestの作成.



Tags: