構成
要はレプリケーション構成。
但し、mongoの場合はプライマリ(マスタ)ノードがダウンした場合に
セカンダリノードをプライマリノードに昇格できるレプリカセットという構成を取る。
要はフェールオーバ時にスレーブのいずれかがプライマリに昇格するのだが
その決定権を持つのがアービターというノードになる。
サーバ | データ | 読み書き |
---|---|---|
プライマリ(マスタ) | 保持する | 読み書き可能 |
スレーブ | 保持する | 読み取りのみ |
アービター | 保持しない | - |
プライマリ(マスタ)
データの更新を唯一受けられるノード。更新されたデータはスレーブへ伝播する。
スレーブ
プライマリからデータを受けるノード。読み取り専用として利用できる。
プライマリがダウンした場合は、アービターによって選ばれたノードがプライマリに昇格する。
アービター
プライマリダウン時にスレーブからプライマリに昇格するノードを選択する。
データは保持しない。必ずしもプライマリ・スレーブ並みの性能を必要としない。
今回はCentOSのサーバを3台用意。
(試したのは実はRedHatだが、CentOSでも同じ)
MongoDBのインストール
リポジトリの追加
# vi /etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=1
インストール
yum install mongo-10gen mongo-10gen-server
起動確認
# service mongod start
Mongoは初回起動時にjournalを作るが、これが3 - 4GBの容量を必要とする。
環境によっては以下のようなログが出て起動に失敗する場合もある。
# cat /var/log/mongodb/mongod.log
(中略)
2016-01-19T11:31:18.522+0900 [initandlisten] ERROR: Insufficient free space for journal files
(中略)
このような場合は空いているデバイスに適当にディレクトリを切って再度起動する。
# mkdir /newMountFreeAvailable/mongo/data
# chown -R mongod:mongod /newMountFreeAvailable/mongo/
# chmod -R 770 /newMountFreeAvailable/mongo/
dbpath=/newMountFreeAvailable/mongo/data <- 変更
起動設定
サーバ起動時にMongoDBが起動するようにしておく。
# chkconfig mongod on
これを3台全てに同じように設定する。
また、レプリカセット用の設定を追加するため、起動が確認できたら全て一度
# service mongod stop
で MongoDB を落としておくこと。
なお、停止に失敗する場合は大抵ロックファイルが原因。
# kill -9 (mongodプロセス番号)
# rm -f /newMountFreeAvailable/mongo/data/mongod.lock
起動できて停止できない場合はdbpathの権限を確認すること。
レプリカセットの作成
インストール同様これも非常に簡単。
各ノードのconfigを変更
- bind_ip=127.0.0.1
+ # bind_ip=127.0.0.1 <- コメントアウトする
+ replSet=myRS <- 好きなレプリカセットの名前を定義したものを追加、3台とも同じ名前にすること
各ノードを起動
# service mongod start
レプリカセットの役割の定義と設定反映
任意のノードでいいはず。
今回はプライマリノードで実施した。
暫定IP表
サーバ | IP |
---|---|
プライマリ | 192.168.100.1 |
スレーブ | 192.168.100.2 |
アービター | 192.168.100.3 |
# mongo
> config = { _id:"myRS",
members:[
{ _id:0, host:"192.168.100.3:27017", arbiterOnly:true },
{ _id:1, host:"192.168.100.1:27017" },
{ _id:2, host:"192.168.100.2:27017" }
]
}
> rs.initiate( config )
(しばらく掛かるが、ここまでで設定が反映される)
> rs.status()
(このコマンドでレプリカセットの状態を確認できる)
スレーブの読み取り専用動作設定
そのままだと、スレーブが読み取り専用として
アクセスできないので以下の設定を行っておく。
# mondodb
> db.getMongo().setSlaveOk()