MongoDB Replica Setの導入構成と問題点


この文書では、MongoDB Replica Setサービスノードの導入と構成手順を説明し、導入スクリプトとテストコードを提供します.特定のバージョンについて、使用中に発生した問題について説明します.
 
1.Replica Set紹介Replica Setは、既存のReplica Pairの代わりにmongodyが1.6バージョンで発売する新しい機能で、2つ以上のノードの自動障害復旧をサポートしています.現在、この機能はリリース前の段階です.その1.5.7(1.6-rc 2)バージョンでは、2010年7月30日にリリースされたばかりのReplica Setのテストバージョンが提供されています.このバージョンの内容はすべてこのバージョンに基づいています.
 
2.サービスの導入と構成テストのために、1台のサーバーで3つのmongodbノードを起動し、ディレクトリを以下のように作成します.
cd /opt/programs/mongodb
mkdir data
mkdir data/20
mkdir data/21
mkdir data/22

 
 
起動スクリプトは次のとおりです.
##########start20.sh
#!/bin/sh
MONGO_HOME=/opt/programs/mongodb
MONGO_DATA=$MONGO_HOME/data
$MONGO_HOME/bin/mongod --port 27020 --replSet rep/rscat:27021 --dbpath $MONGO_DATA/20/ --oplogSize 2048


 
##########start21.sh
#!/bin/sh
MONGO_HOME=/opt/programs/mongodb
MONGO_DATA=$MONGO_HOME/data
$MONGO_HOME/bin/mongod --port 27021 --replSet rep/rscat:27020 --dbpath $MONGO_DATA/21/ --oplogSize 2048

 
 ##########start22.sh
#!/bin/sh
MONGO_HOME=/opt/programs/mongodb
MONGO_DATA=$MONGO_HOME/data
$MONGO_HOME/bin/mongod --port 27022 --replSet rep/rscat:27020 --dbpath $MONGO_DATA/22/ --oplogSize 2048

  
 
3つの異なるコンソールで上記のスクリプトを実行し、3つのサービスノードを起動します.logログから、3つのノードが1つのノードをPrimaryとして交渉し、2つのノードが自動的にSecondaryノードとして機能することがわかります.
 
クライアントを開き、次のようにします.
bin/mongo --port 27020
MongoDB shell version: 1.5.6
connecting to: rscat:27020/test
> use admin
switched to db admin
> cfg = {
... _id: 'rep',
... members: [
... { _id: 0, host: 'rscat:27020' },
... { _id: 1, host: 'rscat:27021' },
... { _id: 2, host: 'rscat:27022' }
... ]
... }

> rs.initiate(cfg)
{
"info" : "Config now saved locally. Should come online in about a 
minute.",
"ok" : 1
}


 
これでReplica Setの構成が完了し、以下でテストできます.
 
3.MongoDBのクライアント付きmongoでテストコンソールでCtrl-CでPrimaryサービスを殺し、サーバのlogログから、クライアントからのクエリーから、他の2つのノードがPrimaryとして1つのノードを協議していることがわかります.起動スクリプトを実行し、殺したばかりのサービスを起動します.
replica setステータスを表示するコマンド:rs.status()
replica set構成を表示するコマンド:rs.conf()
サービスノードがPrimaryであるかどうかを確認するコマンド:db.isMaster();
 
4.javaコードテストこの文章を書いたのは2010年8月2日で、mongodb javaドライブの正式バージョンは2.0で、まだReplica Setのアクセスをサポートしていないので、公式サイトを見てみると、間もなくリリースされる2.1版がReplica Setをサポートしていることがわかりました.Java driverのソースコードをダウンロードし、生成ドライバのjar(mongo-driver.jarと仮称)を自分でコンパイルし、生成したばかりのjarでテストエンジニアリングのmongodbドライバを置き換えます.
テストコードは次のとおりです.
 
package test;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.ServerAddress;

public class TestReplicaSet {
 private int count = 10;
 private Mongo mongo = null ;
 
 @Before
 public void setUp(){
  List<ServerAddress> setList = new ArrayList<ServerAddress>();
  
  try {
   setList.add(new ServerAddress("192.168.0.48", 27020));
   setList.add(new ServerAddress("192.168.0.48", 27021));
   setList.add(new ServerAddress("192.168.0.48", 27022));
  } catch (UnknownHostException e) {
   e.printStackTrace();
  }
  
  mongo = new Mongo(setList);
 }
 
 @Test
 public void testInsertAndGet(){
  DB db = mongo.getDB("A");
  DBCollection col = db.getCollection("B");
  col.drop();
  for(int i = 1; i <= count; i++){
   try{
    col.insert(new BasicDBObject("seq", i+""));
   }catch(MongoException e){

   }
//   System.out.println("i=" + i);
  }
  
  DBCursor cursor = col.find();
  int j = 0;
  while(cursor.hasNext()){
   DBObject o = cursor.next();
   j++;
   assertNotNull(o.keySet());
  }
  assertEquals(j, 10);
 }
}

上記ユニットテストを実行し、成功しました.
 
 
上記のコードを少し変更します.
@Test
 public void testInsertAndGet(){
  DB db = mongo.getDB("A");
  DBCollection col = db.getCollection("B");
  col.drop();
  for(int i = 1; i <= count; i++){
   try{
    col.insert(new BasicDBObject("seq", i+""));
   }catch(MongoException e){

   }

   if(i == 500){
    System.out.println("i=" + i);   
    try {
     Thread.sleep(12000);
    } catch (InterruptedException e) {
    }   
   }
  }

  DBCursor cursor = col.find();
  int j = 0;
  while(cursor.hasNext()){
   DBObject o = cursor.next();
   j++;
   assertNotNull(o.keySet());
  }
//  assertEquals(j, count);
 }


  
Insertが半分(500個)まで実行されたとき、プログラムを一時的に眠らせます.睡眠の12秒以内にPrimaryを殺すサービスは、残りの2つのサービスが迅速に自動的に1つをPrimaryとして選択します.12秒の睡眠が終わった後、プログラムは実行を続けたが、ドライバは新しいPrimaryサービスを見つけることができず、残りのinsertは実行を続けることができず、失敗した.問題発生サーバーバージョン1.5.7 javaドライババージョン(2.0+2.1)/2!!!
 
5.結論:
現在までmongodbのreplica setは開発中であり、コアの機能は基本的に完成しているが、多くの周辺の駆動などはまだ完備されていない.
 
6.参考文献http://osdir.com/ml/mongodb-user/2010-07/msg01519.html(2010.8..2)