MongoDBでゆるふわDB体験

第6回 レプリケーション+シャーディングでMongoDBをもっと使いこなす

この記事を読むのに必要な時間:およそ 4 分

概要

本連載では第4回ではレプリケーション,第5回ではシャーディングについて説明してきましたが,今回はレプリケーションとシャーディングを組み合わせた構成について紹介します。この構成を取ることにより,データを冗長化させつつも,分割して配置することができるため,可用性と読み取り性能を両方向上させることができます。

前回のシャーディングの構成では,単一のmongodをシャーディングサーバに割り当てていましたので,その1つのmongodが障害になると,シャーディングの機能が停止してしまうという問題がありました図1参照)⁠

図1

図1

これを解決するために,シャーディングサーバに単一のmongodではなくレプリカセットを割り当てます。これによりレプリカセット内のmongodに障害が発生してもシャーディングの機能が停止しない構成にすることができます図2参照)⁠

図2

図2

さらに信頼性を高めたい場合は,configサーバを冗長化することができます。configサーバの冗長化は,レプリカセットの非同期レプリケーションとは違い,2フェーズコミットによる同期レプリケーションになります。詳しくはdocs.mongodb.org/manual/administration/sharded-clusters/#config-servers>公式マニュアルを参照ください。

続いて,実際にレプリケーションとシャーディングを組み合わせた構成を作っていきます。

実際に構築する

構築する構成

今回は4台のサーバを使ってレプリカセットとシャーディングを組み合わせた構成を作ります。具体的には,3つのレプリカセットrs0,rs1,rs2をシャードサーバに割り当て,シャーディングを行います。また,レプリカセットを構成するmongodはそれぞれ別のサーバ(サーバA,サーバB,サーバC)上で動作させます。さらにサーバごとにプライマリが1つになるようにします。

configサーバとmongosサーバはフロントサーバ上で動作させます。configサーバの冗長化は行いません。ですので今回は4つのサーバを用います。

図3

図3

4つのサーバが用意できない場合は,1つのサーバで作ることも可能です。全てポートが分かれているためです。その場合,各サーバのIPアドレスを設定する箇所を変更してください。

準備

まず全てのサーバに同じバージョンのMongoDBをダウンロードし展開しておきます。また,dataディレクトリとlogディレクトリを作成します。

全サーバでの作業

cd (MongoDBインストールディレクトリ)
mkdir data log

レプリカセットの作成

最初に,レプリカセットrs0を作ります。各サーバで以下のコマンドを実行し,mongodを起動してください。ポイントは--replSetオプションでレプリカセットを指定する点です。

サーバAでの作業

mkdir  data/node0a
bin/mongod --replSet rs0 --port 30000 --dbpath=data/node0a --logpath=log/node0a --nojournal --fork

サーバBでの作業

mkdir data/node0b
bin/mongod --replSet rs0 --port 30001 --dbpath=data/node0b --logpath=log/node0b --nojournal --fork

サーバCでの作業

mkdir data/node0c
bin/mongod --replSet rs0 --port 30002 --dbpath=data/node0c --logpath=log/node0c --nojournal --fork
[注意]
1つのmongodでジャーナルファイルに3G程度のディスク容量が必要です。試しに使うだけでディスク容量を節約したい場合は,ジャーナルは必要ないので,--nojournalオプションを追加してジャーナルの機能を止めてください。

次にサーバAにてレプリケーションの設定を行います。サーバAにて設定を行うのはサーバAをプライマリにするためです。

サーバAでの作業

bin/mongo localhost:30000 # ←mongoシェルに接続

サーバAのMongoシェルで作業

cfg = {
 _id : "rs0", 
 members : [ 
  { _id : 0, host : "(サーバAのIP):30000" }, 
  { _id : 1, host : "(サーバBのIP):30001" }, 
  { _id : 2, host : "(サーバCのIP):30002" } ] } 
rs.initiate(cfg)  # → "ok" : 1 と表示されれば成功
rs.status()       # → 時間がたつとサーバAがプライマリになります
[注意]
IPアドレスは,1つのレプリカセット内でループバックインターフェース(localhostや127.0.0.1)とネットワークインターフェースを混在させることはできません。つまり(サーバAのIP)の部分は,サーバAのネットワークインターフェースのIPアドレスにしてください。
[参考]
うまくいかないときは,サーバAのmongoシェルで,サーバBやサーバCのmongodに接続できるか確認してみましょう。ネットワークの疎通ができているかの確認になります。また,設定をやり直すためにmongodを停止する場合は,killallコマンドが便利です。

続いて,レプリカセットrs1を同様に作成していきます。

まずmongodを起動します。

サーバAでの作業

mkdir data/node1a
bin/mongod --replSet rs1 --port 30010 --dbpath=data/node1a --logpath=log/node1a --nojournal --fork

サーバBでの作業

mkdir data/node1b
bin/mongod --replSet rs1 --port 30011 --dbpath=data/node1b --logpath=log/node1b --nojournal --fork

サーバCでの作業

mkdir data/node1c
bin/mongod --replSet rs1 --port 30012 --dbpath=data/node1c --logpath=log/node1c --nojournal --fork

続いてレプリケーションを設定しますが,今度はサーバBをプライマリにするためサーバBのmongoシェルで作業します。

サーバBでの作業

bin/mongo localhost:30011

サーバBのMongoシェルでの作業

cfg = {
 _id : "rs1", 
 members : [ 
  { _id : 0, host : "(サーバAのIP):30010" }, 
  { _id : 1, host : "(サーバBのIP):30011" }, 
  { _id : 2, host : "(サーバCのIP):30012" } ] } 
rs.initiate(cfg)  # → "ok" : 1 と表示されれば成功
rs.status()       # → 時間がたつとサーバBがプライマリになります

最後に,レプリカセットrs2を同様に作成していきます。

まずmongodを起動します。

サーバAでの作業

mkdir data/node2a
bin/mongod --replSet rs2 --port 30020 --dbpath=data/node2a --logpath=log/node2a --nojournal --fork

サーバBでの作業

mkdir data/node2b
bin/mongod --replSet rs2 --port 30021 --dbpath=data/node2b --logpath=log/node2b --nojournal --fork

サーバCでの作業

mkdir data/node2c
bin/mongod --replSet rs2 --port 30022 --dbpath=data/node2c --logpath=log/node2c --nojournal --fork

続いてレプリケーションを設定を行いますが,今度はサーバCにて作業を実施します。

サーバCでの作業

bin/mongo localhost:30022

サーバCのMongoシェルでの作業

cfg = {
 _id : "rs2", 
 members : [ 
  { _id : 0, host : "(サーバAのIP):30020" }, 
  { _id : 1, host : "(サーバBのIP):30021" }, 
  { _id : 2, host : "(サーバCのIP):30022" } ] }
rs.initiate(cfg)  # → "ok" : 1 と表示されれば成功
rs.status()       # → 時間がたつとサーバCがプライマリになります

著者プロフィール

藤崎祥見(ふじさきしょうけん)

野村総合研究所 OpenStandia所属。オープンソースのR&Dとセミナー講師を担当。

Debian,Ubuntu,Liferayのコミュニティで活動した後,MongoDBの翻訳に関わり,丸の内MongoDB勉強会を始める。

実家がお寺で,住職の資格を所持する坊主系エンジニア。

Twitter:@syokenz


渡部徹太郎(わたなべてつたろう)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIやサポートの業務に従事。

藤崎と共同で丸の内MongoDB勉強会を始める。

趣味は自宅サーバ。好きなものはLinuxとRuby。

Twitter:@fetarodc


林田敦(はやしだあつし)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIや製品開発業務に従事。

丸の内MongoDB勉強会では広報兼雑用係を務める。

趣味はレザークラフト,ダイビング,スキー,キャンプ,ジェットスキー,カメラ等々。作って滑って撮って潜れるエンジニア。

Facebook:Atsushi Hayashida

コメント

コメントの記入