はじめに
この記事では MongoDB を使って、レプリケーションを試してみます。
レプリケーションを試してみようと思ったきっかけは、結果整合性を理解したかったからです。
結果整合性とは、「更新はそのうち反映される」とか「結果的に整合性が保たれる」とか紹介されています。ちょっと分かりにくいです。
NoSQLの話だと気付き、どのようなDBを使えば結果整合性を確認できそうか調べてみたところ、
MongoDBが良さそうだったので、今回はMongoDBを使うことにしました。
ひとまず、参考になった記事を紹介します。
- 特集:MongoDBで理解する「ドキュメント・データベース」の世界(前編):開発者が知っておくべき、ドキュメント・データベースの基礎 (1/3) - @IT
- MongoDB超入門 - Qiita
- MongoDBでらくらくバッチ処理をやる(Javascriptファイルを実行する)方法 · DQNEO起業日記
-
Getting Started with MongoDB (Node.js Edition) — Getting Started With MongoDB 3.0.4
(特に、「A brief overview of the Node.js Driver」がオススメです。) - MongoDBのレプリケーションが簡単すぎる… - (゚∀゚)o彡 sasata299's blog
この記事では、MongoDBのインストール、データベースサーバの起動、クライアントの起動、データの保存・検索、マスター&スレーブの構成、レプリケーションについて紹介します。
インストール
MongoDB をインストールするために次のコマンドラインを実行します。
$ sudo rudix install mongodb
mongod サーバーを起動
mongod を起動するために、次のコマンドラインを実行します。
$ mongod --dbpath db/mongo
--dbpath でデータベースのパスを指定します。データベースのパスを指定しないでデータベースサーバーを起動したところ、エラーになりました。
mongo クライアントを起動
mongo を起動するために、次のコマンドラインを実行します。
$ mongo
レプリケーションを試してみる
master サーバと slave サーバを用意します。
まずは master サーバを起動します。
$ mongod --master --dbpath db/mongo/master
次に slave サーバーを起動します。
$ mongod --slave --port 27018 --source localhost --dbpath db/mongo/slave
master サーバと slave サーバを用意したので、レプリケーションを試してみます。
レプリケーションを確認するために、クライアントから master サーバに接続して、データを保存します。そして、その保存したデータが slave サーバにも反映されることを確認します。
まずは、クライアントから master サーバと slave サーバに接続して、初期状態を確認します。
クライアントを起動するときに --port で接続先のポート番号を指定することができます。指定しない場合、ポート番号は 27017 になります。
% mongo
MongoDB shell version: 2.6.0
connecting to: test
Server has startup warnings:
2015-08-25T01:19:09.501+0900 [initandlisten]
2015-08-25T01:19:09.501+0900 [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
> show dbs
admin (empty)
local 0.328GB
>
ここでは slave サーバに接続するのに、ポート番号を指定します。
% mongo --port 27018
MongoDB shell version: 2.6.0
connecting to: 127.0.0.1:27018/test
Server has startup warnings:
2015-08-25T01:19:26.509+0900 [initandlisten]
2015-08-25T01:19:26.509+0900 [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
> show dbs
admin (empty)
local 0.078GB
>
次に、master サーバでデータを保存・検索します。
> use study
switched to db study
> db.study.insert({ name: 'taro', age: '123' })
WriteResult({ "nInserted" : 1 })
> db.study.find({ name: 'taro' })
{ "_id" : ObjectId("55db45e6ee1edad9b5e25d59"), "name" : "taro", "age" : "123" }
>
最後に、保存したデータが slave サーバにも反映されることを確認します。
> use study
switched to db study
> db.study.find({ name: 'taro' })
{ "_id" : ObjectId("55db45e6ee1edad9b5e25d59"), "name" : "taro", "age" : "123" }
>
_id の値も同じですね。master サーバで保存したデータが slave サーバにも反映されましたので、レプリケーションが確認できました。
レプリケーションを遅延させてみる
slave サーバーを起動するときに --slavedelay オプションを指定することでレプリケーションを遅延させることができます。
次のようなコマンドラインでレプリケーションを遅延させることができます。
$ mongod --slave --port 27018 --source localhost --slavedelay 180 --dbpath db/mongo/slave
ここではレプリケーションを180秒だけ遅延させるように指定します。
まずは、master サーバでデータを保存・検索します。
> db.study.insert({ name: 'tokyo'})
WriteResult({ "nInserted" : 1 })
> db.study.find({ name: 'tokyo' })
{ "_id" : ObjectId("55db49beee1edad9b5e25d5b"), "name" : "tokyo" }
>
次に、slave サーバで保存したデータを検索します。
> db.study.find({ name: 'tokyo' })
>
データを保存した直後だと検索はヒットしませんが、しばらく待つとヒットするようになります。
> db.study.find({ name: 'tokyo' })
{ "_id" : ObjectId("55db49beee1edad9b5e25d5b"), "name" : "tokyo" }
_id の値も同じですね。
結果整合性の「更新はそのうち反映される」が体験できたと思います。
まとめ
MongoDBを使ってレプリケーションを試してみました。そして、結果整合性を体験しました。
slave サーバで__use study__を忘れると、180秒待ったはずだけど、検索がヒットしないみたいなことになります。気を付けましょう。