mongodb副本集
1.分别在每台机器上建立mongodb
解压mongodb
tar zxvf mongodb-linux-x86_64-2.6.0.tgz mv mongodb-linux-x86_64-2.6.0 /usr/local/mongodb
2.配置环境变量
echo 'export PATH=$PATH:/usr/local/mongodb/bin' >> /etc/profile
3.存放mongodb数据日志文件
mkdir -p /usr/local/mongodb19999/{etc,date,log}
4.启动mongodb
/usr/local/mongodb/bin/mongod --fork --dbpath=/usr/local/mongodb/date --logpath=/usr/local/mongodb/log/mongodb.log --logappend --replSet repset
5.初始化副本集
在三台机器上任意一台机器登陆mongodb
使用admin数据库
#定义副本集配置变量,这里的 _id:”repset” 和上面命令参数“ –replSet repset” 要保持一样 输入一下内容:注意IP和端口换成你自己的
config = { _id:"repset", members:[ {_id:0,host:"192.168.10.92:27017"}, {_id:1,host:"192.168.10.93:27017"}, {_id:2,host:"192.168.10.94:27017"}] }
#输出
{ "_id" : "repset", "members" : [ { "_id" : 0, "host" : "192.168.10.92:27017" }, { "_id" : 1, "host" : "192.168.10.93:27017" }, { "_id" : 2, "host" : "192.168.10.94:27017" } ] }
#初始化副本集配置
rs.initiate(config);
#输出成功
{ "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 }
查看集群节点的状态 rs.status();
#输出
整个副本集已经搭建成功了。
#在主节点PRIMARY 机器上连接到终端:
mongo 127.0.0.1
#建立test 数据库。
use test;
往testdb表插入数据。
> db.testdb.insert({"test1":"testval1"})
> db.testdb.insert({"test1":"testval1"})
repset:SECONDARY> use test;
输出
Sun Dec 29 21:50:48.590 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128
#mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读。
repset:SECONDARY> db.getMongo().setSlaveOk();
#可以看到数据已经复制到了副本集。
repset:SECONDARY> db.testdb.find(); 1 2
#输出
{ "_id" : ObjectId("52c028460c7505626a93944f"), "test1" : "testval1" }
先停掉主节点,查看从节点的日志可以看到经过一系列的投票选择操作,其中1台当选主节点,其他节点会同步数据过来。
查看整个集群的状态,可以看到停掉的服务器为状态不可达。
再启动原来的主节点,原来的主节点变为 SECONDARY。
java程序连接副本集测试。三个节点有一个节点挂掉也不会影响应用程序客户端对整个副本集的读写! public class TestMongoDBReplSet { public static void main(String[] args) { try { List<ServerAddress> addresses = new ArrayList<ServerAddress>(); ServerAddress address1 = new ServerAddress("192.168.10.92" , 27017); ServerAddress address2 = new ServerAddress("192.168.10.93" , 27017); ServerAddress address3 = new ServerAddress("192.168.10.94" , 27017); addresses.add(address1); addresses.add(address2); addresses.add(address3); MongoClient client = new MongoClient(addresses); DB db = client.getDB( "test"); DBCollection coll = db.getCollection( "testdb"); // 插入 BasicDBObject object = new BasicDBObject(); object.append( "test2", "testval2" ); coll.insert(object); DBCursor dbCursor = coll.find(); while (dbCursor.hasNext()) { DBObject dbObject = dbCursor.next(); System. out.println(dbObject.toString()); } } catch (Exception e) { e.printStackTrace(); } } }
常规写操作来说并没有读操作多,所以一台主节点负责写,两台副本节点负责读。 1、设置读写分离需要先在副本节点SECONDARY 设置 setSlaveOk。 2、在程序中设置副本节点负责读操作,如下代码: public class TestMongoDBReplSetReadSplit { public static void main(String[] args) { try { List<ServerAddress> addresses = new ArrayList<ServerAddress>(); ServerAddress address1 = new ServerAddress("192.168.10.92" , 27017); ServerAddress address2 = new ServerAddress("192.168.10.93" , 27017); ServerAddress address3 = new ServerAddress("192.168.10.94" , 27017); addresses.add(address1); addresses.add(address2); addresses.add(address3); MongoClient client = new MongoClient(addresses); DB db = client.getDB( "test" ); DBCollection coll = db.getCollection( "testdb" ); BasicDBObject object = new BasicDBObject(); object.append( "test2" , "testval2" ); coll.insert(object); //读操作从副本节点读取 ReadPreference preference = ReadPreference. secondary(); DBObject dbObject = coll.findOne(object, null , preference); System. out .println(dbObject); } catch (Exception e) { e.printStackTrace(); } } }