[MongoDB] ローカル環境にMongoDBを3つ起動してレプリケーションをセットアップする

handcraft 8/23/2014 8289 5 SQL Server

MongoDB を1つの Windows上に3つ起動して レプリケーションを構成したときのセットアップの覚書を記載します。

検証環境は次の通りです

  • Windows Server 2012 R2
  • MongoDB 2.6.4

今回はMongoDBのレプリケーションのセットアップ検証用に3インスタンスを1つのサーバー上で起動していますが、本来は別々の環境でMongoDBを起動してレプリケーションを構成してください。

1.今回構築するレプリケーションの構成について

今回は プライマリ、セカンダリ ノードを各1台。アービターノードが1台からなるレプリケーション環境を想定して、1台のサーバー上でレプリケーションを構築します。

今回は下図のように C:\mongo に mongodb のインストールファイル一式を配置した環境での作業を前提として説明を記述します。

セットアップ時に使用するコマンドプロンプトもしくは PowerShell は管理者権限で起動していることとします。

2.レプリケーションのセットアップ

まず、3ノード(インスタンス)用にデータファイルを格納するためのフォルダーをセットアップします。コマンドプロンプト(もしくは PowerShell)を起動し データファイル格納用フォルダー用に data フォルダーを作成し、さらに その配下に 3インスタンス用のデータファイル格納用フォルダを作成します。

mkdir data
cd data
mkdir data1
mkdir data2
mkdir arbiter

PowerShellを3つ起動して MongoDBのbinフォルダーに移動します。1サーバー上に複数MongoDBインスタンスを起動するのでポート番号とデータフォルダーのパスを指定して起動します。たとえば次のようにプライマリレプリカセット用のMongoDBインスタンスを起動します。通常の起動方法と異なるのは --replSet パラメーターでレプリカセットの名前を指定している点です。今回は test という名前のレプリカセット名を使用します。

.\mongod.exe --replSet test --dbpath=C:\Mongo\data\node1 --port 40000

同じようにセカンダリおよびアービター用に別々のPowerShellで以下のようにコマンドを入力して、MongoDBを起動します。--replSet で test というレプリカセット名を指定しています。

.\mongod.exe --replSet test --dbpath=C:\Mongo\data\node2 --port 40001

.\mongod.exe --replSet test --dbpath=C:\Mongo\data\arbiter --port 40002

MongoDBを起動したPowerShellの画面には下記のようなログが出力されると思います。これは まだレプリケーションの設定が完了していないためなので今は無視してかまいません。

 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

クライアントシェルを起動して プライマリー用のインスタンスに接続します。ポート番号 40000を指定して起動しているので、次のようにコマンドを入力してアービター用のノードに接続します。

.\mongo.exe --port 40000

プライマリ用のMongoDBに接続したら レプリケーションの初期化を行います。

下記のように rs.initiate() メソッドを呼び出します。

>rs.initiate()

rs.add メソッドを使用して レプリカセットのメンバーを追加します。引数で指定しているのは サーバー名とポート名をコロンで接続した文字列です。アービターとしてセットアップするインスタンスに関しては {arbiterOnly:true} を引数で指定しています。

>rs.add("SC7X03:40001")
>rs.add("SC7X03:40002", {arbiterOnly:true})

構成の確認をしてみます。引き続きシェル上で rs.status() コマンドを実行して PRIMARY, SECONDARY,  ARBITERが追加されていることを確認できます。

>rs.status()

表示された結果の stateStr の値で  PRIMARY, SECONDARY, ARBITER が分かります。レプリカセットのメンバーが 初期化が未完了でオンラインになっていなければ RECOVERING になっている場合があります。

db.isMaster() コマンドでも同様に確認を行えます。 ちなみに、下図のシェルの先頭の test:PRIMARY は レプリカセットの名前と接続しているインスタンスがPRIMARYレプリカセットであることを表しています。出力された内容から データがレプリケートされるホストとポート番号、アービターノードのホスト名とポート番号や自身がプライマリかセカンダリかなど様々なレプリカセットの状態を確認することができます。

以上でレプリケーションの設置ができました。本例では プライマリとセカンダリ、アービターの3インスタンスでレプリケーションを構成しましたが、プライマリ1台、セカンダリ2台の3インスタンスでレプリケーションを構成することもできます。

以降で動作確認をしてみます。

3.レプリケーションの動作確認

レプリケーションのセットアップを行ったので、データを作成してみます。クライアントシェルプログラム(mongo.exe)を起動して プライマリーのインスタンスに接続します。本気時の通りにセットアップを行った場合はポート番号40000のMongoDBインスタンスがプライマリになっていますので PowherShellなどから下のコマンドを入力してMongoDBに接続します。

.\mongo.exe --port 40000

シェル上で 次のようにコマンドを入力して blog データベースを作成し articles コレクションにドキュメントを適当に追加します。

>use blog
switched to db blog
> db.articles.insert({title:"Sample Title", body:"Sample Body", keywords:["Win","Mac"]})
WriteResult({ "nInserted" : 1 })

exit でクライアントを終了します。今度は セカンダリのMongoDBに接続します。上述のようにポート番号を指定して接続できまが、下図のように ホスト名:ポート番号 で接続することもできます。

show dbs コマンドblog データベースが作成されていることを確認します。

use blog でデータベースを blog に切り替えて articles コレクションに対してドキュメントを検索するクエリを発行します(下図参照)。すると 下記のようなエラーが返されます。

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

これは、既定ではレプリケーションが構成された環境ではプライマリに対してのみ データの更新と読み取りが行えるためです。 セカンダリ上で検索用のクエリを発行できるようにするには rs.slaveOk() を実行します。 再度コマンドを実行すると 下図のように ドキュメントを検索することができます。

データがレプリケートされていることを確認したので、フェールオーバーを確認してみます。 プライマリーに接続して use admin コマンドを実行して db.shutdownServer() を実行します。もしくは プライマリのMongoDBを実行している PowerShell 上で Ctrl-C を入力して MongoDBを停止します。

セカンダリーだった MongoDB に接続して rs.isMaster() を実行すると セカンダリーのインスタンスがPRIMARYになっていることを確認できるはずです。さらに rs.status() を実行すると強制終了した MongoDBのインスタンスの stateStr が次のようになっているはずです。

stateStr : "(not reachable/healthy)"

4.まとめ

説明は以上です。簡単ですがレプリケーションを構成してみました。