MongoDB副本集

MongoDB的复制主要分2种,一种是Master-Salve(主从复制),一种是副本集(replica sets),MongoDB4.0之后就不支持主从复制了,官方原话

MongoDB 4.0 removes support for the deprecated master-slave replication. Before you can upgrade to MongoDB 4.0, if your deployment uses master-slave replication, you must upgrade to a replica set.

MongoDB 4.0删除了对主从复制的支持。在升级到MongoDB 4.0之前,如果部署使用主从复制,则必须升级到副本集.本文只讲解副本集的部署步骤。副本集相比较主从复制而言有2点区别:

  1. 该集群没有特定的主数据库。
  2. 如果哪个主数据库宕机了,集群中就会推选出一个从属数据库作为主数据库顶上,这就具备了自动故障恢复功能,很牛X的啊。

角色说明:

1.主库

理论上所有副本集中的数据库都能读取数据,但是系统会默认让主库来完成读取数据的功能

2.辅助副本

主服务器是副本集中唯一接收写操作的成员。MongoDB在主服务器上应用写操作,然后在主服务器的oplog上记录操作。辅助成员复制此日志并将操作应用于其数据集。

3.仲裁者

在主库宕机后重新投票选举出新的主库,它自己不能是主库也不能是辅助副本

副本集配置

1.创建每个库的配置文件,日志文件和数据存档的目录,我本机选择的是 /Data/MongoReplSet/下,MongoReplSet也是我自建的

MongoReplSet下的目录结构

├── conf
│   ├── db1.conf
│   ├── db2.conf
│   └── db3.conf
├── dbs
│   ├── db1
│   ├── db2
│   └── db3
└── logs
    ├── db1.log
    ├── db2.log
    └── db3.log

conf下的配置内容,其中replSet的值是这个副本集的名称

db1.conf

​ dbpath=/Data/MongoReplSet/dbs/db1
​ logpath=/Data/MongoReplSet/logs/db1.log
​ logappend=true
​ noprealloc=true
​ port=27011
​ fork=true
​ replSet=test

db2.conf

​ dbpath=/Data/MongoReplSet/dbs/db2
​ logpath=/Data/MongoReplSet/logs/db2.log
​ logappend=true
​ noprealloc=true
​ port=27012
​ fork=true
​ replSet=test

db3.conf

​ dbpath=/Data/MongoReplSet/dbs/db3
​ logpath=/Data/MongoReplSet/logs/db3.log
​ logappend=true
​ noprealloc=true
​ port=27013
​ fork=true
​ replSet=test

2.进入3个实例中的任何一个,初始化副本集

mongo --port 27011

use admin
config={
    _id:'test',
    members:[
        {_id:1, host:'localhost:27011',priority:2},
        {_id:2, host:'localhost:27012',priority:1},
        {_id:3, host:'localhost:27013',arbiterOnly:true}
    ]
}

rs.initiate(config)

_id:'test'表示副本集名称,与前面conf配置文件中的replSet参数配置的名称要一致。

priority:2表示优先级,优先级越高,副本集初始化时会选举为主库。arbiterOnly:true表示该实例为仲裁节点,不存储数据,只参与投票。

3.rs.status()查看副本集状态

test:SECONDARY> rs.status()
{
    "set" : "test",
    "date" : ISODate("2019-03-05T05:44:28.581Z"),
    "myState" : 2,
    "term" : NumberLong(0),
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(0, 0),
            "t" : NumberLong(-1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1551764659, 1),
            "t" : NumberLong(-1)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1551764659, 1),
            "t" : NumberLong(-1)
        }
    },
    "lastStableCheckpointTimestamp" : Timestamp(0, 0),
    "members" : [
        {
            "_id" : 1,
            "name" : "localhost:27011",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 108,
            "optime" : {
                "ts" : Timestamp(1551764659, 1),
                "t" : NumberLong(-1)
            },
            "optimeDate" : ISODate("2019-03-05T05:44:19Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "could not find member to sync from",
            "configVersion" : 1,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 2,
            "name" : "localhost:27012",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 8,
            "optime" : {
                "ts" : Timestamp(1551764659, 1),
                "t" : NumberLong(-1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1551764659, 1),
                "t" : NumberLong(-1)
            },
            "optimeDate" : ISODate("2019-03-05T05:44:19Z"),
            "optimeDurableDate" : ISODate("2019-03-05T05:44:19Z"),
            "lastHeartbeat" : ISODate("2019-03-05T05:44:28.245Z"),
            "lastHeartbeatRecv" : ISODate("2019-03-05T05:44:28.124Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "configVersion" : 1
        },
        {
            "_id" : 3,
            "name" : "localhost:27013",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 8,
            "lastHeartbeat" : ISODate("2019-03-05T05:44:28.245Z"),
            "lastHeartbeatRecv" : ISODate("2019-03-05T05:44:27.654Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1,
    "operationTime" : Timestamp(1551764659, 1),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1551764659, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

members下面就是整个副片集的成员,其中 27011端口号下面的 infoMessage:'could not find member to sync from',表示它没有可以同步的数据集,因为他是主库,只负责写入

4.主库添加测试数据

test:PRIMARY> use test
switched to db test
test:PRIMARY> db.person.insertMany([{"name":"tom", "age": 20}, {"name":"jack", "age":21}, {"name":"luna", "age":18}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5c7e13b79d270105c2390fcd"),
        ObjectId("5c7e13b79d270105c2390fce"),
        ObjectId("5c7e13b79d270105c2390fcf")
    ]
}

进副库检查

mongo --port 27012
test:SECONDARY> show dbs
2019-03-05T14:14:44.483+0800 E QUERY    [js] Error: listDatabases failed:{
    "operationTime" : Timestamp(1551766483, 1),
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk",
    "$clusterTime" : {
        "clusterTime" : Timestamp(1551766483, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
} :

发现没有权限查看,临时解决方案 执行 rs.slaveOk()

test:SECONDARY>  rs.slaveOk()
test:SECONDARY> show collections
person
test:SECONDARY> db.person.find()
{ "_id" : ObjectId("5c7e652ecf158632e56497cb"), "name" : "jack", "age" : 21 }
{ "_id" : ObjectId("5c7e652ecf158632e56497cc"), "name" : "luna", "age" : 18 }
{ "_id" : ObjectId("5c7e652ecf158632e56497ca"), "name" : "tom", "age" : 20 }

你可能感兴趣的:(MongoDB副本集)