概要
本連載では第4回ではレプリケーション、
前回のシャーディングの構成では、
 
これを解決するために、
 
さらに信頼性を高めたい場合は、
続いて、
実際に構築する
構築する構成
今回は4台のサーバを使ってレプリカセットとシャーディングを組み合わせた構成を作ります。具体的には、
configサーバとmongosサーバはフロントサーバ上で動作させます。configサーバの冗長化は行いません。ですので今回は4つのサーバを用います。
 
4つのサーバが用意できない場合は、
準備
まず全てのサーバに同じバージョンのMongoDBをダウンロードし展開しておきます。また、
cd (MongoDBインストールディレクトリ) mkdir data log
レプリカセットの作成
最初に、
mkdir data/node0a bin/mongod --replSet rs0 --port 30000 --dbpath=data/node0a --logpath=log/node0a --nojournal --fork
mkdir data/node0b bin/mongod --replSet rs0 --port 30001 --dbpath=data/node0b --logpath=log/node0b --nojournal --fork
mkdir data/node0c bin/mongod --replSet rs0 --port 30002 --dbpath=data/node0c --logpath=log/node0c --nojournal --fork
[注意]
1つのmongodでジャーナルファイルに3G程度のディスク容量が必要です。試しに使うだけでディスク容量を節約したい場合は、次にサーバAにてレプリケーションの設定を行います。サーバAにて設定を行うのはサーバAをプライマリにするためです。
bin/mongo localhost:30000 # ←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アドレスは、続いて、
まずmongodを起動します。
mkdir data/node1a bin/mongod --replSet rs1 --port 30010 --dbpath=data/node1a --logpath=log/node1a --nojournal --fork
mkdir data/node1b bin/mongod --replSet rs1 --port 30011 --dbpath=data/node1b --logpath=log/node1b --nojournal --fork
mkdir data/node1c bin/mongod --replSet rs1 --port 30012 --dbpath=data/node1c --logpath=log/node1c --nojournal --fork
続いてレプリケーションを設定しますが、
bin/mongo localhost:30011
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がプライマリになります
最後に、
まずmongodを起動します。
mkdir data/node2a bin/mongod --replSet rs2 --port 30020 --dbpath=data/node2a --logpath=log/node2a --nojournal --fork
mkdir data/node2b bin/mongod --replSet rs2 --port 30021 --dbpath=data/node2b --logpath=log/node2b --nojournal --fork
mkdir data/node2c bin/mongod --replSet rs2 --port 30022 --dbpath=data/node2c --logpath=log/node2c --nojournal --fork
続いてレプリケーションを設定を行いますが、
bin/mongo localhost:30022
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がプライマリになります
シャーディングの設定
いよいよ、
mkdir data/config bin/mongod --configsvr --port 20001 --dbpath data/config --logpath=log/config --nojournal --fork bin/mongos --configdb (フロントサーバのIP):20001 --port 20000 --logpath=log/mongos --chunkSize 1 --fork
[注意]
チャンクサイズを1に設定しているのは、続いて、
bin/mongo localhost:20000/admin
sh.addShard("rs0/(サーバAのIP):30000,(サーバBのIP):30001,(サーバCのIP):30002")   
{ "shardAdded" : "rs0", "ok" : 1 }
sh.addShard("rs1/(サーバAのIP):30010,(サーバBのIP):30011,(サーバCのIP):30012")   
{ "shardAdded" : "rs1", "ok" : 1 }
sh.addShard("rs2/(サーバAのIP):30020,(サーバBのIP):30021,(サーバCのIP):30022")   
{ "shardAdded" : "rs2", "ok" : 1 }
sh.status()
--- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
        {  "_id" : "rs0",  "host" : "rs0/(サーバAのIP):30000,(サーバBのIP):30001,(サーバCのIP):30002" }
        {  "_id" : "rs1",  "host" : "rs1/(サーバAのIP):30010,(サーバBのIP):30011,(サーバCのIP):30012" }
        {  "_id" : "rs2",  "host" : "rs2/(サーバAのIP):30020,(サーバBのIP):30021,(サーバCのIP):30022" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
最後にデータを投入し、
use logdb
for(var i=1; i<=100000; i++) db.logs.insert({"uid":i, "value":Math.floor(Math.random()*100000+1)})
db.logs.count();
db.logs.ensureIndex( { uid : 1 } );
use admin
sh.enableSharding("logdb")
sh.shardCollection("logdb.logs" , { uid : 1 })
sh.status()
次は実際にサーバ障害を発生させ、
障害時の動作実験
これまでの作業で、
 
まず、
watch "bin/mongo localhost:20000/logdb --eval 'db.logs.count() ;'"
このコマンドは2秒に1回logdbデータベースのlogsコレクション数をカウントしているので、
この状態でサーバCの障害を想定して、
killall mongod
するとどうでしょうか? フロントサーバのdb.
まずシャーディングの状況ですが、
bin/mongo localhost:20000/admin sh.status()
見てわかるように、
続いてレプリカセットの状況確認です。
bin/mongo localhost:30020 # →rs2のmongodにログイン rs.status()
おそらく、
次回のテーマ
今回はレプリケーションとシャーディングを組み合わせた構成について紹介しました。本構成を用いることで、
次回の記事ではMonogoDBでサイズの大きなファイルを扱う機能である、


