简介

MongoDB中的副本集(Replica Set)是一组维护相同数据集的mongod服务。 副本集可提供冗余和高可用性,是所有生产部署的基础。

也可以说,副本集类似于有自动故障恢复功能的主从集群。通俗的讲就是用多台机器进行同一数据的异步同步,从而使多台机器拥有同一数据的多个副本,并且当主库宕掉时在不需要用户干预的情况下自动切换其他备份服务器做主库。而且还可以利用副本服务器做只读服务器,实现读写分离,提高负载。

冗余和数据可用性——

复制提供冗余并提高数据可用性。 通过在不同数据库服务器上提供多个数据副本,复制可提供一定级别的容错功能,以防止丢失单个数据库服务器。 在某些情况下,复制可以提供增加的读取性能,因为客户端可以将读取操作发送到不同的服务上,在不同数据中心维护数据副本可以增加分布式应用程序的数据位置和可用性。您还可以为专用目的维护其他副本,例如灾难恢复,报告或备份。

MongoDB中的复制——

副本集是一组维护相同数据集的mongod实例。副本集包含多个数据承载节点和可选的一个仲裁节点。 在承载数据的节点中,一个且仅一个成员被视为主节点,而其他节点被视为次要(从)节点。 主节点接收所有写操作。 副本集只能有一个主要能够确认具有{w:“most”}写入关注的写入; 虽然在某些情况下,另一个mongod实例可能暂时认为自己也是主要的。主要记录其操作日志中的数据集的所有更改,即oplog。

主从复制和副本集区别——

主从集群和副本集最大的区别就是副本集没有固定的“主节点”;整个集群会选出一个“主节点”,当其挂掉后,又在剩下的从节点中选中其他节点为“主节点”,副本集总有一个活跃点(主、primary)和一个或多个备份节点(从、secondary)。

副本集的三个角色两种类型

三种角色:

主要成员(Primary):主要接收所有写操作。就是主节点。

副本成员(Replicate):从主节点通过复制操作以维护相同的数据集,即备份数据,不可写操作,但可以读操作(但需要配置)。是默认的一种从节点类型。

仲裁者(Arbiter):不保留任何数据的副本,只具有投票选举作用,当然也可以将仲裁服务器维护为副本集的一部分,即副本成员同时也可以是仲裁者。也是一种从节点类型。

两种类型

主节点(Primary)类型:数据操作的主要连接点,可读写

次要(辅助、从)节点(Secondaries)类型:数据冗余备份节点,可以读或选举

副本集的创建

创建主节点

建立存档数据和日志的目录

[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27017/log
[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27017/data/db

新建或修改配置文件

vim /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf


systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27017/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27017/data/db"
    journal:
    # 启用持久性日志
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
    bindIp: localhost,192.168.106.10
    port: 27017
replication:
    replSetName: myrs

启动节点服务

[root@localhost ~]# /usr/local/mongodb/bin/mongod -f  /usr/local/mongodb/replica_sets/myrs_27017/mongod.conf

创建副本节点

建立存档数据和日志的目录

[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27018/log
[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27018/data/db

新建或修改配置文件

vim /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf


systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27018/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27018/data/db"
    journal:
    # 启用持久性日志
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27018/log/mongod.pid"
net:
    bindIp: localhost,192.168.106.10
    port: 27018
replication:
    replSetName: myrs

启动节点服务

[root@localhost ~]# /usr/local/mongodb/bin/mongod -f  /usr/local/mongodb/replica_sets/myrs_27018/mongod.conf

创建仲裁节点

建立存档数据和日志的目录

[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27019/log
[root@localhost ~]# mkdir -p /usr/local/mongodb/replica_sets/myrs_27019/data/db

新建或修改配置文件

vim /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf


systemLog:
    destination: file
    path: "/usr/local/mongodb/replica_sets/myrs_27019/log/mongod.log"
    logAppend: true
storage:
    dbPath: "/usr/local/mongodb/replica_sets/myrs_27019/data/db"
    journal:
    # 启用持久性日志
        enabled: true
processManagement:
    fork: true
    pidFilePath: "/usr/local/mongodb/replica_sets/myrs_27019/log/mongod.pid"
net:
    bindIp: localhost,192.168.106.10
    port: 27019
replication:
    replSetName: myrs

启动节点服务

[root@localhost ~]# /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/replica_sets/myrs_27019/mongod.conf

初始化配置副本集和主节点

使用客户端命令连接任一个节点,但这里尽量要连接主节点(27017节点)

mongo --host=localhost --port=27017

此时很多命令无法使用,必须初始化副本集

> rs.initiate()
{
    "info2" : "no configuration specified. Using a default configuration for
the set",
    "me" : "192.168.106.10:27017",
    "ok" : 1
}
myrs:SECONDARY>
myrs:PRIMARY>
# “ok”的值为1,说明创建成功。
# 命令行提示符发生变化,变成了一个从节点角色,此时默认不能读写。稍等片刻,回车,变成主节点

查看副本节点配置

myrs:PRIMARY> rs.conf()
{
    "_id" : "myrs",
    "version" : 1,
    "term" : 1,
    "protocolVersion" : NumberLong(1),
    "writeConcernMajorityJournalDefault" : true,
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.106.10:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {

            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : -1,
        "catchUpTakeoverDelayMillis" : 30000,
        "getLastErrorModes" : {

        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("60d49309bf8b31fd40a975d3")
    }
}
# "_id" : "myrs" :副本集的配置数据存储的主键值,默认就是副本集的名字
# "members" :副本集成员数组,此时只有一个: "host" : "192.168.106.10:27017" ,该
成员不是仲裁节点: "arbiterOnly" : false ,优先级(权重值): "priority" : 1
# "settings" :副本集的参数配置。

添加副本集和仲裁节点

rs.add("192.168.106.10:27018")
# 添加副本节点
rs.addArb("192.168.106.10:27019")
# 添加仲裁节点

副本集的数据读写操作

主节点测试

[root@localhost ~]# mongo --port 27017
use articledb
db.comment.insert(
{
"articleid":"100000",
"content":"今天我们来学习mongodb",
"userid":"1001",
"nickname":"Aaron",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
}
)

从节点测试

[root@localhost ~]# mongo --port 27018
use articledb
db.comment.insert(
{
"articleid":"100000",
"content":"今天我们来学习mongodb",
"userid":"1001",
"nickname":"Aaron",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
}
)
# 无法写入数据
# 这边可以看到报错信息"errmsg" : "not master",
db.comment.find()
# 无法读取数据
# 这边可以看到报错信息"errmsg" : "not master and slaveOk=false",

可以设置从节点有读取权限,不然只能做为备份,不能读取

rs.slaveOk()
# 设置从节点的数据读取权限
db.comment.find()
rs.slaveOk(false)
# 取消从节点的数据读取权限

仲裁者节点不存放任何数据

[root@localhost ~]# mongo --port 27019
rs.slaveOk()
show dbs
# 这边看到报错,报错信息是"errmsg" : "node is not in primary or recovering
state",