现在的位置: 首页 > 综合 > 正文

MongoDB Replica Set的部署配置以及遇到的问题 linux

2014年01月02日 ⁄ 综合 ⁄ 共 4411字 ⁄ 字号 评论关闭

本文介绍了MongoDB Replica Set 服务节点的的部署和配置过程,提供了部署脚本和测试代码。并就特定版本说明了使用中遇到的问题。

 

1.Replica Set介绍
Replica Set是mongoDB将在1.6版本中推出的一项新功能,用来替代已有的Replica Pair,支持多于两个节点的自动的故障恢复,目前这个功能处于发布前的阶段。在它的1.5.7(1.6-rc2)版本中提供了一个Replica Set的测试版本,这个版本在2010年7月30日刚刚发布,本文内容全部基于这个版本。

 

2.服务部署和配置
为了测试,在一台服务器上启动3个mongodb节点,建立目录如下:

Java代码  收藏代码
  1. cd /opt/programs/mongodb  
  2. mkdir data  
  3. mkdir data/20  
  4. mkdir data/21  
  5. mkdir data/22  

 

 

启动脚本如下:

Java代码  收藏代码
  1. ##########start20.sh  
  2. #!/bin/sh  
  3. MONGO_HOME=/opt/programs/mongodb  
  4. MONGO_DATA=$MONGO_HOME/data  
  5. $MONGO_HOME/bin/mongod --port 27020 --replSet rep/rscat:27021 --dbpath $MONGO_DATA/20/ --oplogSize 2048  

 

Java代码  收藏代码
  1. ##########start21.sh  
  2. #!/bin/sh  
  3. MONGO_HOME=/opt/programs/mongodb  
  4. MONGO_DATA=$MONGO_HOME/data  
  5. $MONGO_HOME/bin/mongod --port 27021 --replSet rep/rscat:27020 --dbpath $MONGO_DATA/21/ --oplogSize 2048  

 

Java代码  收藏代码
  1.  ##########start22.sh  
  2. #!/bin/sh  
  3. MONGO_HOME=/opt/programs/mongodb  
  4. MONGO_DATA=$MONGO_HOME/data  
  5. $MONGO_HOME/bin/mongod --port 27022 --replSet rep/rscat:27020 --dbpath $MONGO_DATA/22/ --oplogSize 2048  

  

 

在3个不同的控制台中执行上述脚本,启动3个服务节点,从log日志可以看到,三个节点相互协商出一个节点作为Primary,另外两个自动作为Secondary节点。

 


打开客户端,并按照以下执行:

Java代码  收藏代码
  1. bin/mongo --port 27020  
  2. MongoDB shell version: 1.5.6  
  3. connecting to: rscat:27020/test  
  4. > use admin  
  5. switched to db admin  
  6. > cfg = {  
  7. ... _id: 'rep',  
  8. ... members: [  
  9. ... { _id: 0, host: 'rscat:27020' },  
  10. ... { _id: 1, host: 'rscat:27021' },  
  11. ... { _id: 2, host: 'rscat:27022' }  
  12. ... ]  
  13. ... }  
  14.   
  15. > rs.initiate(cfg)  
  16. {  
  17. "info" : "Config now saved locally. Should come online in about a   
  18. minute.",  
  19. "ok" : 1  
  20. }  

 

至此,Replica Set配置完成,下面可以进行测试了。

 

3.用MongoDB自带客户端mongo进行测试
在控制台中用Ctrl-C杀死Primary服务,从服务器的log日志,以及从客户端查询都可以看到,另外两个节点会协商出其中的一个节点作为Primary。
执行启动脚本,启动刚刚杀死的服务。

查看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驱动。


测试代码如下:

 

Java代码  收藏代码
  1. package test;  
  2.   
  3. import static org.junit.Assert.assertNotNull;  
  4. import static org.junit.Assert.assertEquals;  
  5.   
  6. import java.net.UnknownHostException;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import org.junit.Before;  
  11. import org.junit.Test;  
  12.   
  13. import com.mongodb.BasicDBObject;  
  14. import com.mongodb.DB;  
  15. import com.mongodb.DBCollection;  
  16. import com.mongodb.DBCursor;  
  17. import com.mongodb.DBObject;  
  18. import com.mongodb.Mongo;  
  19. import com.mongodb.MongoException;  
  20. import com.mongodb.ServerAddress;  
  21.   
  22. public class TestReplicaSet {  
  23.  private int count = 10;  
  24.  private Mongo mongo = null ;  
  25.    
  26.  @Before  
  27.  public void setUp(){  
  28.   List<ServerAddress> setList = new ArrayList<ServerAddress>();  
  29.     
  30.   try {  
  31.    setList.add(new ServerAddress("192.168.0.48"27020));  
  32.    setList.add(new ServerAddress("192.168.0.48"27021));  
  33.    setList.add(new ServerAddress("192.168.0.48"27022));  
  34.   } catch (UnknownHostException e) {  
  35.    e.printStackTrace();  
  36.   }  
  37.     
  38.   mongo = new Mongo(setList);  
  39.  }  
  40.    
  41.  @Test  
  42.  public void testInsertAndGet(){  
  43.   DB db = mongo.getDB("A");  
  44.   DBCollection col = db.getCollection("B");  
  45.   col.drop();  
  46.   for(int i = 1; i <= count; i++){  
  47.    try{  
  48.     col.insert(new BasicDBObject("seq", i+""));  
  49.    }catch(MongoException e){  
  50.   
  51.    }  
  52. //   System.out.println("i=" + i);  
  53.   }  
  54.     
  55.   DBCursor cursor = col.find();  
  56.   int j = 0;  
  57.   while(cursor.hasNext()){  
  58.    DBObject o = cursor.next();  
  59.    j++;  
  60.    assertNotNull(o.keySet());  
  61.   }  
  62.   assertEquals(j, 10);  
  63.  }  
  64. }  

 执行上述单元测试,成功。

 

 

把上述代码稍作改变:

Java代码  收藏代码
  1. @Test  
  2.  public void testInsertAndGet(){  
  3.   DB db = mongo.getDB("A");  
  4.   DBCollection col = db.getCollection("B");  
  5.   col.drop();  
  6.   for(int i = 1; i <= count; i++){  
  7.    try{  
  8.     col.insert(new BasicDBObject("seq", i+""));  
  9.    }catch(MongoException e){  
  10.   
  11.    }  
  12.   
  13.    if(i == 500){  
  14.     System.out.println("i=" + i);     
  15.     try {  
  16.      Thread.sleep(12000);  
  17.     } catch (InterruptedException e) {  
  18.     }     
  19.    }  
  20.   }  
  21.   
  22.   DBCursor cursor = col.find();  
  23.   int j = 0;  
  24.   while(cursor.hasNext()){  
  25.    DBObject o = cursor.next();  
  26.    j++;  
  27.    assertNotNull(o.keySet());  
  28.   }  
  29. //  assertEquals(j, count);  
  30.  }  

  

在insert执行到一半(500个)的时候,让程序暂时睡眠。在睡眠的12秒中之内,杀死Primary的服务,此时剩余的两个服务会迅速的自动选出一个作为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)

抱歉!评论已关闭.