Posted at

mongoDBのレプリカセットを構築してRails+mongoidで接続する

More than 3 years have passed since last update.


mongoDBのレプリカセット


前提


  • AWS EC2 AmazonLinux

  • mongoDB 2.6

mongoDBでレプリケーションを作ろうと思ったら、超絶簡単だったので作業メモ。今回は3台構成で作ってみた。AWSでEC2インスタンスを3台使用。プライマリとセカンダリとアービター。


Arbiter(アービター)とは

レプリカセットのプライマリサーバが障害で通信できなくなってしまった時に、どのデータベースをプライマリにするかを決定する役目。Arbiterサーバ自身はデータを持たず、単純に投票権だけを所持している。そのため、サーバスペックは低くても構わない。今回はEC2のt2.microで構成。


mongoDBのインストール&起動

AWS AmazonLinuxのパッケージの場合。公式のマニュアル通り。


/etc/yum.repos.d/mongodb-org-2.6.repo

[mongodb-org-2.6]

name=MongoDB 2.6 Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1

$ sudo yum install -y mongodb-org

$ sudo service mongod start
$ sudo chkconfig mongod on


レプリカの設定

mongoDBサーバ動詞で接続ができるように設定をする。なお、mongoDBのEC2インスタンス自体はAWS VPCのセキュリティ設定でWANからはアクセスされないように設定が必要。グローバルIPが付与されている場合は、簡単に接続されてしまうので注意。

また、レプリカセットの名前を指定する。今回だと3台全て同じreplSet名にする。

$ sudo vi /etc/mongod.conf


/etc/mongod.conf

bind_ip=127.0.0.1 


# コメントアウト
# bind_ip=127.0.0.1

# レプリカセットの名前を追加(全mongoDB共通にする)
replSet=hogeRepl



プライマリ・セカンダリ・アービターの設定

どこか適当なmongoDBにログインし、下記の設定を書き込む。

> config = {_id: 'hogeRepl',

members: [
{_id: 0, host: '172.31.100.10:27017'},
{_id: 1, host: '172.31.100.11:27017'},
{_id: 2, host: '172.31.100.12:27017', arbiterOnly: true},
]
}

> rs.initiate(config)

これだけで、レプリカセットの設定は完了。


レプリカの確認

今のレプリカセットの状態を確認する。

> rs.status()

{
"set" : "hogeRepl",
"date" : ISODate("2015-04-08T00:17:48Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.31.100.10:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1631128,
"optime" : Timestamp(1428452138, 2),
"optimeDate" : ISODate("2015-04-08T00:15:38Z"),
"electionTime" : Timestamp(1426821293, 1),
"electionDate" : ISODate("2015-03-20T03:14:53Z"),
"self" : true
},
{
"_id" : 1,
"name" : "172.31.100.11:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1630985,
"optime" : Timestamp(1428452138, 2),
"optimeDate" : ISODate("2015-04-08T00:15:38Z"),
"lastHeartbeat" : ISODate("2015-04-08T00:17:47Z"),
"lastHeartbeatRecv" : ISODate("2015-04-08T00:17:47Z"),
"pingMs" : 0,
"syncingTo" : "172.31.100.10:27017"
},
{
"_id" : 2,
"name" : "172.31.100.12:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1630983,
"lastHeartbeat" : ISODate("2015-04-08T00:17:48Z"),
"lastHeartbeatRecv" : ISODate("2015-04-08T00:17:48Z"),
"pingMs" : 0
}
],
"ok" : 1
}


セカンダリからデータ閲覧

セカンダリにデータが同期されているか確認するために、セカンダリmongodbに入ってクエリを叩くと以下の様なエラーが出る。

error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

> db.getMongo().setSlaveOk()

# もしくは
> rs.slaveOk()
# 元に戻すには
> db.getMongo().slaveOk = false

ただ、これを設定すると、間違ってセカンダリーで更新処理を行ってしまったりするので運用時はマスターからのみクエリ発行できるようにするのが良い。


mongoidの設定

mongoidの設定は簡単で、プライマリ・セカンダリのホスト名を列挙し、read: primaryでプライマリから読み込むようにするだけ。


/config/mongoid.yml

production:

sessions:
default:
database: hoge
hosts:
- prd-mongo1.hoge.vpc:27017
- prd-mongo2.hoge.vpc:27017
options:
max_retries: 30
retry_interval: 1
read: primary
options: