MongoDBでレプリカセット試してみた。

mongodb レプリカセットとは

MongoDB JPより

レプリカセットとは
MongoDBはレプリカセットと呼ばれる冗長構成(クラスタ)を組むことができます。
レプリカセットには唯一のプライマリノード(PRIMARY)とセカンダリノード(SECONDARY)複数を含める事ができ、クラスタに対する書き込みは全てPRIMARYに対して行われます。
PRIMARYに対する更新は速やかに全てのSECONDARYにコピーされ安全に保持されます。

マニュアルとコンセプトはこちらに

Replication Concepts

Master、Slave、Arbiter(仲裁者)で構成必要
Master – Slaveでは完全レプリケーションを行い、
ArbiterはMasterが死んだ時にSlaveをMasterに変更して運用を続行できる機能があるようです。
レプリカセットの構成には最低でも3つのノードが必要ということですね。

MongoDB起動

とりあえず1台でmongodbを複数起動してレプリカセットのテストをおこないます。

データディレクトリ作成


// /tmp以下にデータを格納するディレクトリを作成します
$ mkdir /tmp/node1
$ mkdir /tmp/node2d
$ mkdir /tmp/node3

MongoDB違うポートで起動


// ポートとデータディレクトリとレプリを指定してMongoDBサーバを起動する
$ sudo mongod --replSet myapp --dbpath /tmp/node1 --port 40001
$ sudo mongod --replSet myapp --dbpath /tmp/node2 --port 40002
$ sudo mongod --replSet myapp --dbpath /tmp/node3 --port 40003

マスタのポート 40001
スレーブのポート 40002
アービターのポート 40003

MongoDBへアクセスしてレプリカ設定を行う

マスタ設定

マスタ用のMongoDBにアクセス


$ mongo --port 40001

Mongoのマスタ上でレプリカセット設定


> rs.initiate()
> var conf=rs.conf()
> conf
{
    "_id" : "myapp",
    "version" : 1,
    "members" : [
        {
            "_id" : 0,
            "host" : "vagrant-ubuntu-raring-64:40000"
        }
    ]
}
> rs.add("vagrant-ubuntu-raring-64:40002")
{ "ok" : 1 }
> rs.add("vagrant-ubuntu-raring-64:40003", {arbiterOnly: true})
{ "down" : [ "vagrant-ubuntu-raring-64:40003" ], "ok" : 1 }

host名は適度自分の環境に合わせてください。

Slave設定


$ mongo --port 40002

スレーブ設定


> db.getMongo().setSlaveOk()

レプリカセットのサマリ表示

masterへ接続


$ mongo --port 40001


> db.isMaster()
{
    "setName" : "myapp",
    "ismaster" : true,
    "secondary" : false,
    "hosts" : [
        "vagrant-ubuntu-raring-64:40001",
        "vagrant-ubuntu-raring-64:40002"
    ],
    "arbiters" : [
        "vagrant-ubuntu-raring-64:40003"
    ],
    "primary" : "vagrant-ubuntu-raring-64:40001",
    "me" : "vagrant-ubuntu-raring-64:40001",
    "maxBsonObjectSize" : 16777216,
    "localTime" : ISODate("2013-05-31T05:23:58.282Z"),
    "ok" : 1
}

Master接続


$ mongo --port 40001

> use hogehoge
switched to db hogehoge
myapp:PRIMARY> db.hogehoge.insert({title: "Oliver Twist"})
myapp:PRIMARY> show dbs
hogehoge   0.203125GB
local   2.0146484375GB

Slave 接続


$ mongo --port 40002
> use hogehoge
> db.hogehoge.find()
{ "_id" : ObjectId("51a8348ce65a785a8e794bf4"), "title" : "Oliver Twist" }
> db.hogehoge.insert({title:"abc store", sell:true, isbm:"03084494"})
not master

# slaveに対しては書き込みを行おうとするとエラー

レプリカセットのテスト

Masterをおもむろに落とす (CTRL+Cとかkillコマンドとかむしろいろいろな方法で)
しばらくするとSlaveがMasterに変更されする

スレーブだったDBへ接続


$ mongo --port 40002
> PRIMARY

MasterだったMongoDBを起動するとスレーブに降格されている....はず。

マスターだったDBへ接続


$ mongo --port 40001
> SECONDARY

MasterとSlaveが入れ替わっている...はず。