在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
复制 1.主从复制 1.1 选项 1.2 添加以及删除源 cat >> /etc/hosts <<EOF 192.168.27.212 test02 192.168.27.213 test03 192.168.27.214 test01 EOF 启动从节点时可以用--source指定主节点,也可以在shell中配置这个源。 > db.sources.insert({ "host" : "192.168.27.212:10001"}); 立即查询会得到插入的文档: > use local switched to db local > db.sources.find(); { "_id" : ObjectId("530be5049ab1ad709cfe66b7"), "host" : "test02:10001" 当同步完成后,文档更新: > db.sources.find(); { "_id" : ObjectId("530bf0ab058022d91574c79c"), "host" : "test02:10001", "source" : "main", "syncedTo" : Timestamp(1393291443, 1), "dbsNextPass" : { "foo" : true, "test" : true } } 2.副本集 mongod --fork --dbpath /data/node2 --logpath /data/mongodb.log --port 10001 --logappend --replSet myrepl/test03:10002 mongod --fork --dbpath /data/node3 --logpath /data/mongodb.log --port 10002 --logappend --replSet myrepl/test02:10001 副本集的亮点是自检测功能:在其中指定单台服务器后,MongoDB会自动搜索并连接其余的节点。 > db.runCommand({"replSetInitiate" : { ... "_id" : "myrepl", ... "members" : [ ... { ... "_id" : 1, ... "host" : "test02:10001" ... }, ... { ... "_id" : 2, ... "host" : "test03:10002" ... } ... ]}}) { "startupStatus" : 4, "info" : "myrepl/test03:10002", "ok" : 0, "errmsg" : "all members and seeds must be reachable to initiate set" } (1)"_id" : "myrepl" 副本集的名称 config = {"_id" : "myrepl", "members" : [ {"_id" : 0, "host" : "test02:10001"}, {"_id" : 1, "host" : "test03:10002"} ]} rs.initiate(config); rs.status(); myrepl:SECONDARY> rs.status(); { "set" : "myrepl", "date" : ISODate("2014-02-25T02:17:39Z"), "myState" : 2, "syncingTo" : "test03:10002", "members" : [ { "_id" : 0, "name" : "test02:10001", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 968, "optime" : Timestamp(1393294457, 1), "optimeDate" : ISODate("2014-02-25T02:14:17Z"), "errmsg" : "syncing to: test03:10002", "self" : true }, { "_id" : 1, "name" : "test03:10002", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 48, "optime" : Timestamp(1393294457, 1), "optimeDate" : ISODate("2014-02-25T02:14:17Z"), "lastHeartbeat" : ISODate("2014-02-25T02:17:38Z"), "lastHeartbeatRecv" : ISODate("2014-02-25T02:17:39Z"), "pingMs" : 1, "syncingTo" : "test02:10001" } ], "ok" : 1 } 如果这时候把primary节点停掉,在secondary节点执行写操作,就会发生如下错误提示: myrepl:SECONDARY> db.test.insert({name : "baobao"}); not master 如果只有2台Mongodb,配置复制集群还不够安全,需要1个外在角色调整各个节点的角色。 mongod --fork --dbpath /data/node1 --logpath /data/mongodb.log --port 10003 --logappend --replSet myrepl/test02:10001,test03:10002 myrepl:PRIMARY> rs.addArb("test01:10003"); { "ok" : 1 } 查看各节点的状态: myrepl:PRIMARY> rs.status(); { "set" : "myrepl", "date" : ISODate("2014-02-25T02:30:26Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "test02:10001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1735, "optime" : Timestamp(1393295409, 1), "optimeDate" : ISODate("2014-02-25T02:30:09Z"), "self" : true }, { "_id" : 1, "name" : "test03:10002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 204, "optime" : Timestamp(1393295409, 1), "optimeDate" : ISODate("2014-02-25T02:30:09Z"), "lastHeartbeat" : ISODate("2014-02-25T02:30:26Z"), "lastHeartbeatRecv" : ISODate("2014-02-25T02:30:24Z"), "pingMs" : 1, "syncingTo" : "test02:10001" }, { "_id" : 2, "name" : "test01:10003", "health" : 1, "state" : 6, "stateStr" : "UNKNOWN", "uptime" : 17, "lastHeartbeat" : ISODate("2014-02-25T02:30:25Z"), "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"), "pingMs" : 1, "lastHeartbeatMessage" : "still initializing" } ], "ok" : 1 } 对比三个节点对自身节点性质的判断: myrepl:PRIMARY> db.isMaster(); { "setName" : "myrepl", "ismaster" : true, "secondary" : false, "hosts" : [ "test03:10002", "test02:10001" ], "arbiters" : [ "test01:10003" ], "primary" : "test03:10002", "me" : "test03:10002", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "localTime" : ISODate("2014-02-25T02:32:29.760Z"), "ok" : 1 } myrepl:SECONDARY> db.isMaster(); { "setName" : "myrepl", "ismaster" : false, "secondary" : true, "hosts" : [ "test02:10001", "test03:10002" ], "arbiters" : [ "test01:10003" ], "primary" : "test03:10002", "me" : "test02:10001", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "localTime" : ISODate("2014-02-25T02:33:50.144Z"), "ok" : 1 } myrepl:SECONDARY> db.isMaster(); { "setName" : "myrepl", "ismaster" : false, "secondary" : true, "hosts" : [ "test02:10001", "test03:10002" ], "arbiters" : [ "test01:10003" ], "primary" : "test03:10002", "me" : "test02:10001", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "localTime" : ISODate("2014-02-25T02:33:50.144Z"), "ok" : 1 } 在节点配置中修改priority键,来配置成标准节点或者被动节点。 3.在从服务器上执行操作 myrepl:SECONDARY> db.test.find(); error: { "$err" : "not master and slaveOk=false", "code" : 13435 } 需要告知Mongodb集群,从哪台机器上进行读操作: myrepl:SECONDARY> rs.slaveOk(); myrepl:SECONDARY> db.test.find(); { "_id" : ObjectId("530bfc79eee2c2ce39f9cd95"), "name" : "caoqing" } { "_id" : ObjectId("530bfd8f3627cb16c15dcb32"), "name" : "xiaobao" } 3.2 用从节点做数据处理 4.工作原理 myrepl:PRIMARY> db.oplog.$main.help(); 查看oplog的内容: myrepl:PRIMARY> use local; switched to db local myrepl:PRIMARY> show collections; me oplog.rs replset.minvalid slaves startup_log system.indexes system.replset myrepl:PRIMARY> db.oplog.rs.find(); { "ts" : Timestamp(1393294283, 1), "h" : NumberLong(0), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } } { "ts" : Timestamp(1393294457, 1), "h" : NumberLong("-8949844291534979055"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : ObjectId("530bfc79eee2c2ce39f9cd95"), "name" : "caoqing" } } { "ts" : Timestamp(1393294735, 1), "h" : NumberLong("677282438107403253"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : ObjectId("530bfd8f3627cb16c15dcb32"), "name" : "xiaobao" } } { "ts" : Timestamp(1393295409, 1), "h" : NumberLong("5171944912929102944"), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "Reconfig set", "version" : 2 } } myrepl:PRIMARY> 文档包含的键如下: myrepl:PRIMARY> db.slaves.find(); { "_id" : ObjectId("530bfbdc911eb0ac3bf2aa8b"), "config" : { "_id" : 1, "host" : "test03:10002" }, "ns" : "local.oplog.rs", "syncedTo" : Timestamp(1393295409, 1) } 从节点也在本地数据库中存放状态。在me集合中存放从节点的唯一标识符,在sources集合中存放源或节点的列表。 myrepl:SECONDARY> db.me.find(); { "_id" : ObjectId("530bfbdc911eb0ac3bf2aa8b"), "host" : "test03" } 主节点和从节点都跟踪从节点的更新状况,这个是通过存放在"syncedTO"中的时间戳来完成的。 myrepl:PRIMARY> db.runCommand("getlasterror") { "n" : 0, "lastOp" : Timestamp(0, 0), "connectionId" : 3525, "err" : null, "ok" : 1 } 指定"w"选项后,可以使用"wtimeout"选项,表示以毫秒为单位的超时。 5.管理 db.printReplicationInfo() 命令查看oplog状态。 myrepl:PRIMARY> db.printReplicationInfo(); configured oplog size: 997.7892578125001MB log length start to end: 1126secs (0.31hrs) oplog first event time: Tue Feb 25 2014 10:11:23 GMT+0800 (CST) oplog last event time: Tue Feb 25 2014 10:30:09 GMT+0800 (CST) now: Wed Feb 26 2014 02:07:23 GMT+0800 (CST) 输出信息包括oplog日志的大小,操作日志记录的起始时间。 myrepl:PRIMARY> db.printSlaveReplicationInfo(); source: test03:10002 syncedTo: Tue Feb 25 2014 10:30:09 GMT+0800 (CST) = 56533 secs ago (15.7hrs) source: test01:10003 no replication info, yet. State: ARBITER 输出信息包括从库的主机名,port信息等。 # rm -rf /data/node2/local* 为大型的oplog预分配空间非常耗费时间,且可能导致主节点停机时间增加,尽可能的手动预分配数据文件。 PS:副本集replSet具体配置 mongod --fork --dbpath /data/node2 --logpath /data/mongodb.log --port 10001 --logappend --replSet myrepl/test03:10002 mongod --fork --dbpath /data/node3 --logpath /data/mongodb.log --port 10002 --logappend --replSet myrepl/test02:10001 1.2 初始化副本集 config = {"_id" : "myrepl", "members" : [ {"_id" : 0, "host" : "test02:10001"}, {"_id" : 1, "host" : "test03:10002"} ]} rs.initiate(config); rs.status(); myrepl:SECONDARY> rs.status(); { "set" : "myrepl", "date" : ISODate("2014-02-25T02:17:39Z"), "myState" : 2, "syncingTo" : "test03:10002", "members" : [ { "_id" : 0, "name" : "test02:10001", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 968, "optime" : Timestamp(1393294457, 1), "optimeDate" : ISODate("2014-02-25T02:14:17Z"), "errmsg" : "syncing to: test03:10002", "self" : true }, { "_id" : 1, "name" : "test03:10002", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 48, "optime" : Timestamp(1393294457, 1), "optimeDate" : ISODate("2014-02-25T02:14:17Z"), "lastHeartbeat" : ISODate("2014-02-25T02:17:38Z"), "lastHeartbeatRecv" : ISODate("2014-02-25T02:17:39Z"), "pingMs" : 1, "syncingTo" : "test02:10001" } ], "ok" : 1 } 1.3 增加一个仲裁节点,只负责仲裁,不做数据存储。 mongod --fork --dbpath /data/node1 --logpath /data/mongodb.log --port 10003 --logappend --replSet myrepl/test02:10001,test03:10002 myrepl:PRIMARY> rs.addArb("test01:10003"); { "ok" : 1 } 2 MongoDB:Replica Set 增加节点 myrepl:PRIMARY> rs.conf(); { "_id" : "myrepl", "version" : 2, "members" : [ { "_id" : 0, "host" : "test02:10001" }, { "_id" : 1, "host" : "test03:10002" }, { "_id" : 2, "host" : "test01:10003", "arbiterOnly" : true } ] } 现有三个节点,两台standard节点,一台arbiter节点。 mkdir -p /data/node/ touch /data/mongodb.log 2.2.2 安装mongodb: tar zxf mongodb-linux-x86_64-2.4.9.tgz mv mongodb-linux-x86_64-2.4.9 /opt/mongodb echo "export PATH=$PATH:/opt/mongodb/bin" >>/etc/profile source /etc/profile mongod --config ~/.mongodb.conf 2.2.3 创建新从节点配置文件: cat >> ~/.mongodb.conf <<EOF fork = ture port = 10005 dbpath = /data/node logpath = /data/mongodb.log logappend = true replSet = myrepl EOF 2.2.4 更改节点信息
cat /etc/sysconfig/network cat >> /etc/hosts << EOF 192.168.27.214 test01 192.168.27.212 test02 192.168.27.213 test03 192.168.27.215 test04 192.168.27.216 test05 EOF 2.2.5 判断节点是否是主节点
myrepl:PRIMARY> rs.isMaster(); { "setName" : "myrepl", "ismaster" : true, "secondary" : false, "hosts" : [ "test02:10001", "test03:10002" ], "arbiters" : [ "test01:10003" ], "primary" : "test02:10001", "me" : "test02:10001", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "localTime" : ISODate("2014-02-25T19:23:22.286Z"), "ok" : 1 } 2.2.6 增加新从节点到replSet myrepl:PRIMARY> rs.add("192.168.27.215:10004"); # 增加arbiter节点的方法:myrepl:PRIMARY> rs.addArb("test01:10003"); 2.2.7 再次查看Replica Set状态信息 myrepl:PRIMARY> rs.conf(); { "_id" : "myrepl", "version" : 3, "members" : [ { "_id" : 0, "host" : "test02:10001" }, { "_id" : 1, "host" : "test03:10002" }, { "_id" : 2, "host" : "test01:10003", "arbiterOnly" : true }, { "_id" : 3, "host" : "192.168.27.215:10004" } ] } 3. 测试 4. 把standard节点变为passive节点 myrepl:PRIMARY> cfg = rs.conf() { "_id" : "myrepl", "version" : 3, "members" : [ { "_id" : 0, "host" : "test02:10001" }, { "_id" : 1, "host" : "test03:10002" }, { "_id" : 2, "host" : "test01:10003", "arbiterOnly" : true }, { "_id" : 3, "host" : "192.168.27.215:10004" } ] } myrepl:PRIMARY> cfg.members[3].priority = 0; myrepl:PRIMARY> rs.reconfig(cfg); myrepl:PRIMARY> rs.conf(); { "_id" : "myrepl", "version" : 4, "members" : [ { "_id" : 0, "host" : "test02:10001" }, { "_id" : 1, "host" : "test03:10002" }, { "_id" : 2, "host" : "test01:10003", "arbiterOnly" : true }, { "_id" : 3, "host" : "192.168.27.215:10004", "priority" : 0 } ] } |
请发表评论