見出し画像

ローカル環境でMongoDBのReplicationを構成する方法

こんにちは。RGA(リアルグローブ・オートメーティッド)でインフラエンジニアをしている張です。

少し前、学習のためローカル環境にMongoDBを3つ起動してレプリケーションをセットアップしてみようと試みました。インターネット上に同じようなセットアップに関連する情報は多々存在しているものの、実際に手を動かしてみて、少し異なるところがあったので、自分がやりやすい方法をまとめてみます。

構築に使用した環境は以下の通りです。

MongoDB: 5.0.2
MacOS: Big Sur 11.5.2

1. データファイルを格納するためのフォルダを作成

まずは、データファイル格納用フォルダ用に data フォルダーを作成し、さらにその配下に3つインスタンス用のデータファイル格納用フォルダ(db1, db2, db3)を作成します。

mkdir -p db{1,2,3}

2. 設定ファイル(mongod.conf)を作成

続いて、設定ファイルを作成します。MongoDBの設定ファイル(mongod.conf)のオプションについては、MongoDBの公式ドキュメントを参照。
db1, db2, db3はそれぞれに対して作成する必要があります。

ディレクトリ構成

ディレクトリ構成は以下のようになります。

|data
|--db1
|  |--mongod.conf
|--db2
|  |--mongod.conf
|--db3
|  |--mongod.conf  

ポート番号

ポートは下記で設定しました。

  • db1: 28017

  • db2: 28018

  • db3: 28019

設定ファイルの内容

db1用のmongod.confは下の内容で設定しています。

systemLog:
    destination: file
    path: {usr}/data/db1/mongod.log
    logAppend: true
storage:
    dbPath: {usr}/data/db1
net:
    bindIp: 0.0.0.0
    port: 28017        # ポート番号
replication:
    replSetName: rs0   # レプリカセット名:rs0
processManagement:
    fork: true

db2, db3 は上記の設定を各自のフォルダにコピーして、path、dbPath、portをそれぞれ修正します。

3. 設定ファイルを適用

下記のコマンドで設定ファイルを適用します。

mongod -f {DBディレクトリ名}/mongod.conf

例えばdb1のmongod.confを適用する場合は以下のようになります。

mongod -f db1/mongod.conf

設定ファイルの適用が正しくできた場合、下記のようなメッセージが表示されますので、確認してください。

about to fork child process, waiting until server is ready for connections.
forked process: 87472
child process started successfully, parent exiting

db2, db3 も同様に適用します。

適用してから、稼働状況をさらに確認したい場合、psコマンドを実行するのが手っ取り早いですね。

ps -ef | grep mongod

4. インスタンスに接続

設定ファイルが適用できたら、下記のコマンドで db1 にアクセスします。

mongod --port 28017 --quiet

※ --quietは、接続情報を簡潔に表示されるオプション

1) rs.initiate()でレプリカセットのメンバーを追加

rs.initiate()は、新しいレプリカセットの設定した時に初期化を行うメソッドです。便利のため、rs.initiate()でセットするとき、db1, db2, db3のホスト情報をmembersという設定フィールドに追加しておきます。

※参照:rs.initiate()について

rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:28017"},{_id: 1, host: "localhost:28018"},{_id: 2,host:"localhost:28019"}]})

上記のコマンド叩いた結果は下のようになります。

{ "ok" : 1 }

上のスクショでは、下のように表示されています。

rs0:SECONDARY>

もう一回Enterを押すと、下のように切り替わります。

rs0:PRIMARY>

ここまでで、すでに"rs0"というレプリカセットのメンバー(db1)にアクセスできたことになります。

※PRIMARYやSECONDARYは何ものかは、こちらのページ「Replica Set Members」を参照。

The replica set can have at most one primary. If the current primary becomes unavailable, an election determines the new primary.

簡単に説明すると、デフォルトの設定ではDBが初期化された時に SECONDARYと認められます。上記の説明から、現在のレプリカセットは、PRIMARY(1つ)、SECONDARY(2つ)があると明らかになります。

次の動作を検証するため、もう一回Enterを押すと、db1をPRIMARYに変更します。

この時点では、db1がPRIMARYとして設定されていて、まだログインしていないdb2, db3はSECONDARYになています。次のステップで、各メンバーのstateStrで確認できます。もちろん、db1 が一時的に止まってしまった場合、db2, db3のどれかがPRIMARYに変更されます。

2) メンバーの追加状況を確認

こちらのコマンドでステータスを確認します。

rs.status()

上図で、db1 のstateStrが”PRIMARY”になっているのがわかります。

5. レプリカセットの稼働状況を確認

db1 が "PRIMARY"である限り、書き込みと読み込みができるので、db1 にデータを挿入してみて、db2 側から様子を確認してみます。

なお、本ブログでは"Arbiter"というメンバーをスキップしていますので、時間があればこちらのドキュメントをチェックしてみてください→"Arbiter"について

メンバー db2 にアクセスする

mongo localhost:28018 --quiet

上記のコマンドでdb2 にアクセスしてから、db1の内容が見れるのかを、下記のコマンドで試します。

db.test.find()

しかし、下のようなエラーメッセージが表示されました。

"errmsg" : "not master and slaveOk=false",

このメッセージは、まだ db1 の slave になってないよ、db1は知らない人、という意味ですので、両方の関係を築き上げましょう。

最初は、rs.slaveOk()で試してみます。ただし、このメソッドは次のリリースで削除されるそうなので、推奨のrs.secondaryOk()を使うのが良いでしょう。

db.test.find()

で もう一回確認してみると、問題が解決していることがわかります。ただし、下のスクショのように、testというDBにはデータがないから、何も表示されません。

データ同期確認

では、メンバー db1 にデータを追加して、db2 から同期さるか確認して見ましょう。

まず、db1に適当なデータをinsertします。

db.test.insert({a:0})

insert直後にdb2 側で確認してみます。

期待通りdb1 で insert した{a: 0}が db2 側で見れました!

ローカル環境だから、すぐに反映されたと感じましが、レプリカセットのメンバーが遠距離であっても、数十ミリ秒程度の遅延しか掛からないと言われています。

db1 を kill してから db2 が昇格

次に、psで db1 のプロセス番号を確認し、kill してみましょう。

今回は auxを使ってみます。 ※ef派とaux派がこれからもpeace&loveで暮らしていくように。余談→あなたはPS -EF派なのか、AUXF派なのかをちょっとだけまとめてみた

ps aux | grep mongod

db1のプロセスコードは87472がわかった。

kill 87472

しばらく待ってから、db1 が稼働していないことが確認できる。

db2がPRIMARYに昇格されることも確認できる。

おまけ - db1を再起動したら、どうなるのか?

先ほどkillしたdb1を再起動したら、db1またPRIMARYに昇格されるか、それともそのままSECONDARYとして起動するでしょうか?

どうやら、db2がPRIMARYとして稼働している限り、db1はSECONDARYとして動作するようです。

以上MongoDBのレプリケーションをセットアップする方法でした。

――――――――――――――――――――――――――――――――――

執筆者プロフィール:張 媛
文系出身、IT派遣会社で3年間オンプレ環境でのWeb開発しながら、Pythonなどの言語を自学し、GCPプレミアサービスパートナー会社に転職してクラウドでWeb開発を引き続き、DWH構築、データ可視化などを経験。
RGAでは、Azureでのインフラ構築、運用監視ツール開発、OSS導入支援などの業務に従事。

【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。

IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!

お問合せは以下の窓口までお願いいたします。

【お問い合わせ窓口】
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp