レプリケーションとフェイルオーバーを自動で行う
(ノ・・)ン。。。。。。(((●コロコロッ
mongodbを使い始めて数日。
何となくコツをつかめてきている気がする。
遊びでヘロヘロ使う分にはいいのだが、
実運用で考えるならいろいろ考慮しなきゃいけない点がでてくる。
言わずもがな最も重要視してたのが「耐障害性」。
レプリケーションが出来るというのはあらかじめ情報として入手していた。
が、いざ使ってみるとどんな感じなのかはやはり使ってみないとわからない。
ということでレプリケーションの設定をしてみることにした。
調べてみるとレプリケーションの種類がいくつかあるっぽい。
- Master-Slave レプリケーション
- Replica Pairs
- Replica Sets
- Limited [Master-Master Replication]
この内、一番高機能なのが
Replica Sets(レプリカセット)
ver1.6からの新機能だそうだが、
幸いyumで入れたmongodbは1.6.4で対応しているようだった。
ということでreplica setsでレプリケーションしてみることにした。
[More:]
replica setsとは?
Replica setsは従来のmaster/slave レプリケーションの機能をより強化するものとして、各ノードメンバーに対してフェイルオーバーやリカバリーの機能を自動で提供します。
http://www.mongodb.org/display/DOCSJP/Replica+Sets
レプリケーションというとMySQLのイメージが強い。
マスター1台にスレーブが複数台あって、
書き込みをマスターに、読み込みをスレーブにという棲み分け。
スレーブはロードバランシングして負荷分散。
マスターはこけたら自力で復旧って感じ。
mongodbのreplica setsを使うことで、
マスターがこけたら自動で別のノード(サーバー)がマスターに切り替わるようだ。
接続側が対応している必要もあるようだが、
幸いPHPは対応してるっぽい。
また、このノード(サーバー)はプライマリにしないなど指定もできるとか。
arbiterという仲介ノード(サーバー)を加えることでより正確なフェイルオーバーが実現できる。
とか。
(データの欠落は発生しそうだけど。)
(トランザクションをきちんとしなきゃいけない基幹系やECは向いてないというのは
この辺にもあるのかもね。)
arbiterは多ければ多いほど良いみたいなので、
構成としては
・arbiter: アプリケーションサーバ側に設置
・member: データベース用サーバに設置(マスターとスレーブに区別は付けない)
という具合になりそうだ。
では設定は難しいのかというとそんなことはない。
コンフィグを少し加えてサーバー再起動、
コマンドをちょこっと打ち込む感じ。
インストールをyumでやっているのが前提。
参考:
mongodbをyumでCentOSにインストール(UTF8対応版)
サーバは2台192.168.0.1, 192.168.0.2用意したとする。
ポートはデフォルトの27017。
●コンフィグ
すべてのサーバーに以下の行を加えて再起動
replSet = repl
("repl"は任意の文字列。グループ名という感じ。)
●プライマリーサーバに接続しレプリケーション指示
$ mongo 192.168.0.1:27017
> config = {_id: 'repl', members: [{_id: 0, host: '192.168.0.1:27017'}]};
> rs.initiate(config);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
> exit;
●スレーブサーバ追加
$ mongo 192.168.0.1:27017
> rs.add({_id: 1, host: '192.168.0.2:27017'});
> exit;
●レプリケーションの確認
$ mongo 192.168.0.1:27017
> db.first.save({"foo":"bar"});
> exit;
$ mongo 192.168.0.2:27017
> rs.slaveOk();
> db.first.find(
{ "_id" : ObjectId("4f0d2dcac1e42cfef32bf5b2"), "foo" : "bar" });
> exit;
一応動作はしている模様。
挙動を見る限りデータベース側をロードバランシングをする必要は無いみたい。
---- ハマりポイント ----
rs.initiate()を単独実行するとHOSTがIPでは無くホスト名になって、
スレーブ側から参照できなくなるという状態に陥った。
(スレーブ側のログに出てた)
コンフィグを置き換えようとコマンドを打っても現状確認が優先されてエラー。
ファイル全削除から設定をしなおし。
サーバを起動したときにプロセスが落ちる現象があった。
どうも起動の際にデータベースファイルを作成するみたいだが、
作成するファイルが大きすぎるようだ。
(約1GBを作ろうとしてプロセスダウン)
コンフィグに以下の設定を追加(100MBの場合)
oplogSize = 100
---- おまけ ----
●状態の確認
$ mongo 192.168.0.1:27017
> rs.status();
> exit;
●主従の確認
$ mongo 192.168.0.1:27017
> db.isMaster();
> exit;
●コンフィグ再設定
$ mongo 192.168.0.1:27017
> config = rs.conf();
> // config配列を書き換え
> rs.reconfig(config);
参考:
http://www.mongodb.org/display/DOCSJP/Replica+Set+Tutorial
http://d.hatena.ne.jp/doryokujin/20101102/1288651712