本节主要讲解MongoDB的副本集,

掌握这个知识点将大幅度提高你对MongoDB的掌握程度!

------------------------------------------------------

1 关于副本集:

一组服务器,其中一个是主服务器---处理客户端请求,

还有多个备份服务器,用于保存服务器的数据副本。

如果主服务器挂了,备份服务器会自动将其中一个成员升级为新的主服务器!

2 rs.status()

fubenji:PRIMARY> rs.status() 
 
 { 
 
  "set" : "fubenji", 
 
  "date" : ISODate("2014-08-04T06:55:44Z"), 
 
  "myState" : 1, 
 
  "members" : [ 
 
   { 
 
    "_id" : 1, 
 
    "name" : "192.168.56.254:27017", 
 
    "health" : 1, 
 
    "state" : 1, 
 
    "stateStr" : "PRIMARY", 
 
    "uptime" : 82, 
 
    "optime" : Timestamp(1407111729, 1), 
 
    "optimeDate" : ISODate("2014-08-04T00:22:09Z"), 
 
    "electionTime" : Timestamp(1407135287, 1), 
 
    "electionDate" : ISODate("2014-08-04T06:54:47Z"), 
 
    "self" : true 
 
   }, 
 
   { 
 
    "_id" : 2, 
 
    "name" : "192.168.56.66:27018", 
 
    "health" : 1, 
 
    "state" : 2, 
 
    "stateStr" : "SECONDARY", 
 
    "uptime" : 60, 
 
    "optime" : Timestamp(1407111729, 1), 
 
    "optimeDate" : ISODate("2014-08-04T00:22:09Z"), 
 
    "lastHeartbeat" : ISODate("2014-08-04T06:55:42Z"), 
 
    "lastHeartbeatRecv" : ISODate("2014-08-04T06:55:42Z"), 
 
    "pingMs" : 0, 
 
    "lastHeartbeatMessage" : "syncing to: 192.168.56.254:27017", 
 
    "syncingTo" : "192.168.56.254:27017" 
 
   } 
 
  ], 
 
  "ok" : 1 
 
 }


3 db.isMaster()

fubenji:PRIMARY> db.isMaster() 
 
 { 
 
  "setName" : "fubenji", 
 
  "setVersion" : 1, 
 
  "ismaster" : true, 
 
  "secondary" : false, 
 
  "hosts" : [ 
 
   "192.168.56.254:27017", 
 
   "192.168.56.66:27018" 
 
  ], 
 
  "primary" : "192.168.56.254:27017", 
 
  "me" : "192.168.56.254:27017", 
 
  "maxBsonObjectSize" : 16777216, 
 
  "maxMessageSizeBytes" : 48000000, 
 
  "maxWriteBatchSize" : 1000, 
 
  "localTime" : ISODate("2014-08-04T06:55:10.951Z"), 
 
  "maxWireVersion" : 2, 
 
  "minWireVersion" : 0, 
 
  "ok" : 1 
 
 }

 4 为什么备份节点默认情况下会拒绝读请求?

因为备份节点一般会落后于主节点,所以为了安全起见,默认拒绝读请求!

fubenji:SECONDARY> show collections
 2014-08-04T15:25:12.642+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131

解决方案:

根据 rs.help()得知运行命令rs.slaveOk()  !!!

5 备份节点不能接受写入请求

只能通过复制功能写入数据,不接受客户端的写入请求!

6 通过命令关闭数据库

db.adminCommand({"shutdown":1})

----------------------------------------------

7 创建副本集

在192.168.56.254上
cd  /usr/local/mongodb-linux-x86_64-2.6.1/
./bin/mongod  --dbpath ./data/db --port 27017 --replSet fubenji/192.168.56.66:27018

数据路径 /data/db 

在192.168.56.66上
cd /usr/local/mongodb-linux-x86_64-2.6.1
./bin/mongod --dbpath ./data/db --port 27018 --replSet fubenji/192.168.56.254:27017 --fork --logpath ./log/0.log
这样,mongodb就安装完毕。


[然后还需要rs.initiate()执行下...]

或者采用

db.runCommand(
 {"replSetInitiate":
      {
       "_id":"副本集名字",
       "members":
              [
                { "_id":1,"host":"name:port"},
                { "_id":1,"host":"name:port"}
              ]
      }
 }

------------------------------------------

8 关于副本集的知识点

如果创建全新的副本集,配置可以发给任何一个成员

如果已经有1个有数据的成员,必须将配置发给有数据的。

如果已经有2个或者以上的成员,就无法配置一个副本集!

重新配置副本集时,主节点要先退化为普通节点,以便接受新的配置,然后恢复!

所以有一会儿副本集中暂时无主节点,之后一切恢复正常!

9 临时添加一个成员

rs.add("ip:port")

10删除一个成员

rs.remove("ip:port")

11 查看当前配置信息

fubenji:PRIMARY> rs.config()
 {
  "_id" : "fubenji",
  "version" : 1,
  "members" : [
   {
    "_id" : 1,
    "host" : "192.168.56.254:27017"
   },
   {
    "_id" : 2,
    "host" : "192.168.56.66:27018"
   }
  ]
 }

 12 一次性增加或者删除多个机器的方法

创建新的配置文件,然后调用rs.reconfig...

13 关于选举中的大多数的计算公式

假如成员有N个。

不废话,看图

成员总数

大多数

1

1

2

2

3

2

4

3

5

3

6

4

7

4

---比如,有个副本集有5个成员,3个不可用,2个正常。

由于5个成员必须有3个才达到大多数的要求,

所以剩下的2个节点无法选择出主节点,

如果这2个节点中正好有1个是主节点,发现不能获得大多数节点的支持

则会自动退化成备份节点。

这样,群的状态从(4个备份节点,1个主节点)--》(3个不可达,1个主, 一个备份)--》(3个不可达,2个备份节点)

很清楚吧!

14 为什么要制定这样貌似弱爆了的规则?

目的在于防止一个群根据规则,分裂后产生2个主节点!

================================

15 如何选举?

假如吧,主节点真的挂了,汗,这多么悲剧,

让我们痛定思痛,生活还是要继续的,来推选出新的主节点吧!

当备份节点无法与主节点连通时,它会联系并请求其它的成员推选自己为主节点

这就是“毛遂自荐”的来历!!! :)

如果某个成员可以得到大多数的投票,它就会成为主节点!

但是,如果大多数的成员中只有1个否决了本次选举,选举就会取消!

注意:一张否决票带来-10000分,一张赞成票就是1分

这就是所谓的一票否决权啊。。。相当于联合国了!

------------------

希望成为主节点的数据必须使用复制将自己的数据更新为最新,其它成员会检查的,

候选人的最后一条操作要比它能连通的其它所有成员都晚!