1、概述

复制集是一个带有故障转移的主从集群。是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复。

复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举 产生一个主结点。该主结点被称为primary,一个或多个从结点被称为secondaries。primary结点基本上就是master结点,不同之 处在于primary结点在不同时间可能是不同的服务器。如果当前的主结点失效了,复制集中的其余结点将会试图选出一个新的主结点。

复制集模式的好处是,一切自动化。首先,复制集模式本身做了大量的管理工作,自动管理从节点,确保数据不会不一致。其次,主节点挂掉后,会自动判断集群中的服务器并进行故障转移,推举新的主节点。

一个复制集集群支持1-7台服务器,在一个复制集中各个服务器数据保持完全一致。

在一个复制集集群中,各个服务器有以下几种状态:

  1. Primary 主节点,一个复制集有且仅有一台服务器处于Primary状态,只有主节点才对外提供读写服务。如果主节点挂掉,复制集将会投票选出一个备用节点成为新的主节点。
  2. Secondary 备用节点,复制集允许有多台Secondary,每个备用节点的数据与主节点的数据是完全同步的。
  3. Recovering 恢复中,当复制集中某台服务器挂掉或者掉线后数据无法同步,重新恢复服务后从其他成员复制数据,这时就处于恢复过程,数据同步后,该节点又回到备用状态。
  4. Arbiter 仲裁节点,该类节点可以不用单独存在,如果配置为仲裁节点,就主要负责在复本集中监控其他节点状态,投票选出主节点。该节点将不会用于存放数据。如果没有仲裁节点,那么投票工作将由所有节点共同进行。
  5. Down 无效节点,当服务器挂掉或掉线时就会处于该状态。

复制集的从节点读请求,也是在各个Driver层设置slaveOk的值来实现的。

 

2、示例

  • 创建一个包含三个服务器的mongodb 的副本集   (不要把 --auth 开启了 不然会使得 复本集之间无法通信)
/usr/local/mongodb/mongod -dbpath=/data/mongodbreplset/19 --fork --port 27019 --logpath=/usr/local/mongodb/log/mongodbreplset/m19.log --logappend --replSet rsdemo --smallfiles

/usr/local/mongodb/mongod -dbpath=/data/mongodbreplset/18 --fork --port 27018 --logpath=/usr/local/mongodb/log/mongodbreplset/m18.log --logappend --replSet rsdemo --smallfiles

/usr/local/mongodb/mongod -dbpath=/data/mongodbreplset/17 --fork --port 27017 --logpath=/usr/local/mongodb/log/mongodbreplset/m17.log --logappend --replSet rsdemo --smallfiles

 

 

  •  执行以下操作 初始化复制集
rsdemo:PRIMARY> var rsconf={
... _id:'rsdemo',
... members:[
... {_id:0,host:'192.168.0.108:27017'},
... {_id:1,host:'192.168.0.108:27018'},
... {_id:2,host:'192.168.0.108:27019'}
... ]}
rsdemo:PRIMARY> rs.reconfig(rs)
rs(     rsconf
rsdemo:PRIMARY> rs.reconfig(rsconf)   //rs.initiate(rsconf)
{ "ok" : 1 }
  •  查看复制集合的状态:rs.status()
rsdemo:PRIMARY> rs.status()
{
    "set" : "rsdemo",
    "date" : ISODate("2015-11-16T14:19:12Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.0.108:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 880,
            "optime" : Timestamp(1447683546, 1),
            "optimeDate" : ISODate("2015-11-16T14:19:06Z"),
            "lastHeartbeat" : ISODate("2015-11-16T14:19:10Z"),
            "lastHeartbeatRecv" : ISODate("2015-11-16T14:19:11Z"),
            "pingMs" : 0,
            "syncingTo" : "192.168.0.108:27019"
        },
        {
            "_id" : 1,
            "name" : "192.168.0.108:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 916,
            "optime" : Timestamp(1447683546, 1),
            "optimeDate" : ISODate("2015-11-16T14:19:06Z"),
            "lastHeartbeat" : ISODate("2015-11-16T14:19:11Z"),
            "lastHeartbeatRecv" : ISODate("2015-11-16T14:19:11Z"),
            "pingMs" : 0,
            "syncingTo" : "192.168.0.108:27019"
        },
        {
            "_id" : 2,
            "name" : "192.168.0.108:27019",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 940,
            "optime" : Timestamp(1447683546, 1),
            "optimeDate" : ISODate("2015-11-16T14:19:06Z"),
            "electionTime" : Timestamp(1447682643, 1),
            "electionDate" : ISODate("2015-11-16T14:04:03Z"),
            "self" : true
        }
    ],
    "ok" : 1
}

 

  •  查看配置信息 rs.conf()
rsdemo:PRIMARY> rs.conf()
{
    "_id" : "rsdemo",
    "version" : 3,
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.0.108:27017"
        },
        {
            "_id" : 1,
            "host" : "192.168.0.108:27018"
        },
        {
            "_id" : 2,
            "host" : "192.168.0.108:27019"
        }
    ]
}
rsdemo:PRIMARY> 

 

  •  查看是不是主节点
rsdemo:PRIMARY> rs.isMaster(
... )
{
    "setName" : "rsdemo",
    "setVersion" : 3,
    "ismaster" : true,
    "secondary" : false,
    "hosts" : [
        "192.168.0.108:27019",
        "192.168.0.108:27018",
        "192.168.0.108:27017"
    ],
    "primary" : "192.168.0.108:27019",
    "me" : "192.168.0.108:27019",
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2015-11-16T14:51:16.795Z"),
    "maxWireVersion" : 2,
    "minWireVersion" : 0,
    "ok" : 1
}

 

  • 测试复制集合
  1.  首先在主节点创建demo库 
  2.  for 循环添加1000条数据
  3.  主库查看是不是存在
  4.  检查副本集成员是不是含有该记录
rsdemo:PRIMARY>  for(var i=0;i<1000;i++){db.demo.insert({count:i})}
WriteResult({ "nInserted" : 1 })
rsdemo:PRIMARY> show dbs
admin  (empty)
demo   0.031GB
local  0.094GB
rsdemo:PRIMARY> use demo
switched to db demo
rsdemo:PRIMARY> db.demo.find()
{ "_id" : ObjectId("563e24b2a731ac9621c37650"), "age" : 18, "name" : "赵兴壮" }
{ "_id" : ObjectId("5649e70fff8e3af9408ff52f"), "count" : 0 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff530"), "count" : 1 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff531"), "count" : 2 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff532"), "count" : 3 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff533"), "count" : 4 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff534"), "count" : 5 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff535"), "count" : 6 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff536"), "count" : 7 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff537"), "count" : 8 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff538"), "count" : 9 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff539"), "count" : 10 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53a"), "count" : 11 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53b"), "count" : 12 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53c"), "count" : 13 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53d"), "count" : 14 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53e"), "count" : 15 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53f"), "count" : 16 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff540"), "count" : 17 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff541"), "count" : 18 }
Type "it" for more

 

rsdemo:SECONDARY> rs.slaveOk()// 注意
rsdemo:SECONDARY> db.demo.find()
{ "_id" : ObjectId("563e24b2a731ac9621c37650"), "age" : 18, "name" : "赵兴壮" }
{ "_id" : ObjectId("5649e70fff8e3af9408ff52f"), "count" : 0 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff530"), "count" : 1 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff531"), "count" : 2 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff532"), "count" : 3 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff533"), "count" : 4 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff534"), "count" : 5 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff535"), "count" : 6 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff536"), "count" : 7 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff537"), "count" : 8 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff538"), "count" : 9 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff539"), "count" : 10 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53a"), "count" : 11 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53b"), "count" : 12 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53c"), "count" : 13 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53d"), "count" : 14 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53e"), "count" : 15 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff53f"), "count" : 16 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff540"), "count" : 17 }
{ "_id" : ObjectId("5649e70fff8e3af9408ff541"), "count" : 18 }
Type "it" for more
rsdemo:SECONDARY> 

 



 

没有无缘无故的荣耀