LoginSignup
27
31

More than 5 years have passed since last update.

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

Posted at

mongoDBのレプリカセット

前提

  • AWS EC2 AmazonLinux
  • mongoDB 2.6

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

Untitled (1).png

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:
27
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
31