转自http://zouqingyun.blog.51cto.com/782246/1679771 html
由三个节点组成的 复制集 为网络故障或是其余的系统故障提供了足够的冗余。该复制集也有足够的分布式读操做的能力。复制集应该保持奇数个节点,这也就保证了 选举 能够正常的进行nginx
用3台已有的 mongod 实例来部署一个由三个节点组成的 复制集mongodb
mongodb-1 192.168.3.31
docker
mongodb-2 192.168.3.32数据库
mongodb-3 192.168.3.33数组
在生产环境中,咱们应该将每一个节点部署在独立的机器上,并使用标准的MongoDB端口 27017 。使用 bind_ip 参数来限制访问MongoDB的应用程序的地址。安全
若使用了异地分布式架构的复制集,请确保多数 mongod 实例节点位于主数据中心中。bash
确保各个节点之间能够正常通信,且各个客户端都处于安全的可信的网络环境中。能够考虑如下事项:网络
创建虚拟的专用网络。确保各个节点之间的流量是在本地网络范围内路由的。(Establish a virtual private network. Ensure that your network topology routes all traffic between members within a single site over the local area network.)架构
配置链接限制来防止未知的客户端链接到复制集。
配置网络设置和防火墙规则来对将MongoDB的端口仅开放给应用程序,来让应用程序发的进出数据包能够与MongoDB正常交流。
最后请确保复制集各节点能够互相经过DNS或是主机名解析。咱们须要配置DNS域名或是设置 /etc/hosts 文件来配置。
MongoDB的安装文档请参考http://docs.mongoing.com/manual/core/read-preference.html
1.修改配置文件/etc/mongod.conf
#添加要复制的复制集名称 replSet=testrs0 #添加这一行 #重启mongodb服务 Stopping mongod: [ OK ] Starting mongod: [ OK ] [root@mongodb-1 ~]# netstat -anpt |grep mon tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN 1836/mongod tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 1836/mongod #mongodb-2,mongodb-3同样的操做,过程略 #配置本地hosts解析 [root@mongodb-1 ~]# tail -3 /etc/hosts 192.168.3.31 mongodb-1 192.168.3.32 mongodb-2 192.168.3.33 mongodb-3
2.初始化复制集
> rs.initiate() #初始化 { "info2" : "no configuration explicitly specified -- making one", "me" : "mongodb-1:27017", "ok" : 1 } testrs0:OTHER> rs.status() #查看状态 { "set" : "testrs0", "date" : ISODate("2015-08-06T02:07:24.851Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-1:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 108, "optime" : Timestamp(1438826836, 1), "optimeDate" : ISODate("2015-08-06T02:07:16Z"), "electionTime" : Timestamp(1438826836, 2), "electionDate" : ISODate("2015-08-06T02:07:16Z"), "configVersion" : 1, "self" : true } ], "ok" : 1 }
3.将mongodb-2,mongodb-3加入到节点中
#经过 rs.add() 来将剩下的节点加入复制集 testrs0:PRIMARY> rs.add("mongodb-2:27017") #支持域名解析 { "ok" : 1 } testrs0:PRIMARY> rs.add("mongodb-3:27017") { "ok" : 1 } #查看最后结果 testrs0:PRIMARY> rs.status() { "set" : "testrs0", "date" : ISODate("2015-08-06T02:10:13.116Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-1:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 277, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "electionTime" : Timestamp(1438826836, 2), "electionDate" : ISODate("2015-08-06T02:07:16Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "mongodb-2:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 19, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "lastHeartbeat" : ISODate("2015-08-06T02:10:12.956Z"), "lastHeartbeatRecv" : ISODate("2015-08-06T02:10:12.029Z"), "pingMs" : 1, "syncingTo" : "mongodb-1:27017", "configVersion" : 3 }, { "_id" : 2, "name" : "mongodb-3:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 8, "optime" : Timestamp(1438827004, 1), "optimeDate" : ISODate("2015-08-06T02:10:04Z"), "lastHeartbeat" : ISODate("2015-08-06T02:10:12.968Z"), "lastHeartbeatRecv" : ISODate("2015-08-06T02:10:12.976Z"), "pingMs" : 5, "syncingTo" : "mongodb-1:27017", "configVersion" : 3 } ], "ok" : 1 } #在mongodb-1上查看节点状态 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : true, #表示当前节点是master节点 "secondary" : false, "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-1:27017", "electionId" : ObjectId("55c2c154479b3bb0dbd4a66a"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:11:40.419Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-2上查看节点状态 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : false, "secondary" : true, #显示当前节点是slave状态 "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-2:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:08:11.009Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-3上查看结果 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 3, "ismaster" : false, "secondary" : true, #显示是slave状态 "hosts" : [ "mongodb-1:27017", "mongodb-2:27017", "mongodb-3:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-3:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:08:55.896Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
4.在主节点上建立数据,从节点是否获取到
testrs0:PRIMARY> use testdb switched to db testdb testrs0:PRIMARY> db.testcoll.insert({Name: "test",Age: 50,Gender: "F"}) WriteResult({ "nInserted" : 1 }) testrs0:PRIMARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" }
在从节点上查询,是不能够直接查询,要使用一个命令rs.slave()把本身提高为从节点
testrs0:SECONDARY> rs.slaveOk() testrs0:SECONDARY> use testdb switched to db testdb testrs0:SECONDARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" }
5、中止mongodb-1的服务
[root@mongodb-1 ~]# hostname mongodb-1 [root@mongodb-1 ~]# /etc/init.d/mongod stop Stopping mongod: [ OK ] [root@mongodb-1 ~]# netstat -tunlp |grep mon #在mongodb-2上查看节点状态 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : true, "secondary" : false, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "192.168.3.32:27017", "electionId" : ObjectId("55c2d5c12885e541bfce06ea"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:36:54.961Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-3上查看节点状态 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : false, "secondary" : true, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "192.168.3.33:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:37:41.152Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #在mongodb-2上查看数据 testrs0:PRIMARY> db.testcoll.find() { "_id" : ObjectId("55c2c34071cd36e46b63e280"), "Name" : "test", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c4ca71cd36e46b63e281"), "Name" : "docker", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c58271cd36e46b63e282"), "Name" : "nginx", "Age" : 50, "Gender" : "F" } { "_id" : ObjectId("55c2c863581ac81241af5a9b"), "Name" : "test", "Age" : 50, "Gender" : "F" }
从新启动mongodb-1的服务
[root@mongodb-1 ~]# /etc/init.d/mongod start Starting mongod: [ OK ] [root@mongodb-1 ~]# netstat -tunlp |grep mon tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN 1882/mongod tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 1882/mongod
查看mongodb-1的节点状态,默认会是slave状态
testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 7, "ismaster" : false, "secondary" : true, #结果显示的是slave状态 "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "192.168.3.32:27017", "me" : "mongodb-1:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:48:14.075Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
6.定义优先级
使用 rs.conf() 来查看 复制集配置对象 :
testrs0:SECONDARY> rs.conf() { "_id" : "testrs0", "version" : 7, "members" : [ { "_id" : 0, "host" : "mongodb-1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #优先级为1 "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 1, "host" : "192.168.3.32:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 2, "host" : "192.168.3.33:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } } }
在主节点把mongodb-1的优先级定义为2,让它成为主节点
将复制集配置对象复制给一个变量(如 mycfg )。而后经过该变量对该节点设置优先级。而后经过 rs.reconfig()来更新复制集配置。
注意,设置优先级用这个命令mycfg.members[数组中第几个节点].priority = 2
#首先定义变量mycfg testrs0:PRIMARY> mycfg=rs.conf() { "_id" : "testrs0", "version" : 7, "members" : [ { "_id" : 0, "host" : "mongodb-1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 1, "host" : "192.168.3.32:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 }, { "_id" : 2, "host" : "192.168.3.33:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } } } #设置成员优先级 testrs0:PRIMARY> mycfg.members[0].priority = 2 #设置优先级为2 2 testrs0:PRIMARY> rs.reconfig(mycfg) #从新读取配置文件 { "ok" : 1 } #查看mongodb-2的状态 testrs0:SECONDARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 8, "ismaster" : false, "secondary" : true, #已经由以前的master变成slave了 "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "mongodb-1:27017", "me" : "192.168.3.32:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T03:49:23.235Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 } #查看mongodb-1的状态 testrs0:PRIMARY> rs.isMaster() { "setName" : "testrs0", "setVersion" : 8, "ismaster" : true, #已经从以前的slave变成master状态了 "secondary" : false, "hosts" : [ "mongodb-1:27017", "192.168.3.32:27017", "192.168.3.33:27017" ], "primary" : "mongodb-1:27017", "me" : "mongodb-1:27017", "electionId" : ObjectId("55c2cc1fe60875284b735753"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2015-08-06T02:54:07.059Z"), "maxWireVersion" : 3, "minWireVersion" : 0, "ok" : 1 }
复制集参考
Replication Methods in the mongo Shell 命令 描述 rs.add() 为复制集新增节点。 rs.addArb() 为复制集新增一个 arbiter rs.conf() 返回复制集配置信息 rs.freeze() 防止当前节点在一段时间内选举成为主节点。 rs.help() 返回 replica set 的命令帮助 rs.initiate() 初始化一个新的复制集。 rs.printReplicationInfo() 以主节点的视角返回复制的状态报告。 rs.printSlaveReplicationInfo() 以从节点的视角返回复制状态报告。 rs.reconfig() 经过从新应用复制集配置来为复制集更新配置。 rs.remove() 从复制集中移除一个节点。 rs.slaveOk() 为当前的链接设置 slaveOk 。不推荐使用。使用 readPref() 和 Mongo.setReadPref() 来设置 read preference 。 rs.status() 返回复制集状态信息。 rs.stepDown() 让当前的 primary 变为从节点并触发 election 。 rs.syncFrom() 设置复制集节点从哪一个节点处同步数据,将会覆盖默认选取逻辑。
复制集数据库命令
命令 描述 replSetFreeze 防止当前节点在一段时间内选举成为主节点。 replSetGetStatus 返回复制集的状态报告。 replSetInitiate 初始化一个新的复制集。 replSetMaintenance 开启活关闭维护模式,维护模式将使 secondary 进入 RECOVERING 状态。 replSetReconfig 为已存在的复制集应用新的配置。 replSetStepDown 强制当前的 primary *降职*变为 secondary ,并触发选举。 replSetSyncFrom 覆盖默认的复制来源选取逻辑。 resync 强制 mongod 从新从 master 进行初始化复制。仅在主-从模式。 applyOps 内部命令应用 oplog 在如今的数据集上。 isMaster 返回该节点的角色信息,包括是否为主节点。 getoptime 内部命令,返回optime。