MongoDB主从复制
主从复制是 MongoDB 最早使用的复制方式, 该复制方式易于配置,并且可以支持任意数量的从节点服务器,与使用单节点模式相比有如下优点:
在从服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
可配置读写分离,主节点负责写操作,从节点负责读操作,将读写压力分开,提高系统的稳定性。
MongoDB 的主从复制至少需要两个服务器或者节点。其中一个是主节点,负责处理客户端请求,其它的都是从节点,负责同步主节点的数据。
主节点记录在其上执行的所有写操作,从节点定期轮询主节点获取这些操作,然后再对自己的数据副本执行这些操作。由于和主节点执行了相同的操作,从节点就能保持与主节点的数据同步。
主节点的操作记录称为oplog(operation log),它被存储在 MongoDB 的 local 数据库中。oplog 中的每个文档都代表主节点上执行的一个操作。需要重点强调的是oplog只记录改变数据库状态的操作。比如,查询操作就不会被存储在oplog中。这是因为oplog只是作为从节点与主节点保持数据同步的机制。
然而,主从复制并非生产环境下推荐的复制方式,主要原因如下两点:
a.灾备都是完全人工的 如果主节点发生故障失败,管理员必须关闭一个从服务器,然后作为主节点重新启动它。然后应用程序必须重新配置连接新的主节点。
b.数据恢复困难 因为oplog只在主节点存在,故障失败需要在新的服务器上创建新的oplog,这意味着任意存在的节点需要重新从新的主节点同步oplog。
因此,在新版本的MongoDB中已经不再支持使用主从复制这种复制方式了,取而代之的是使用副本集复制方式。
MongoDB副本集
MongoDB副本集(Replica Set)其实就是具有自动故障恢复功能的主从集群,和主从复制最大的区别就是在副本集中没有固定的“主节点;整个副本集会选出一个节点作为“主节点”,当其挂掉后,再在剩下的从节点中选举一个节点成为新的“主节点”,在副本集中总有一个主节点(primary)和一个或多个备份节点(secondary)。
除了primary和secondary之外,副本集中的节点还可以是以下角色:
成为primary | 对客户端可见 | 参与投票 | 延迟同步 | 复制数据 | |
---|---|---|---|---|---|
Default | √ | √ | √ | ∕ | √ |
Secondary-Only | ∕ | √ | √ | ∕ | √ |
Hidden | ∕ | ∕ | √ | ∕ | √ |
Delayed | ∕ | √ | √ | √ | √ |
Arbiters | ∕ | ∕ | √ | ∕ | ∕ |
Non-Voting | √ | √ | ∕ | ∕ | √ |
关于副本集的基础概念,可以参考:https://blog.csdn.net/pengjunlee/article/details/83958794
官方帮助文档:https://docs.mongodb.com/manual/replication/
官方推荐的副本集最小配置需要有三个节点:一个主节点接收和处理所有的写操作,两个备份节点通过复制主节点的操作来对主节点的数据进行同步备份。
配置副本集
环境准备
副本集各节点IP如下:
10.1.1.68
10.1.1.69
10.1.1.70
首先,参照如下文章先对三个MongoDB 节点进行安装:
https://blog.csdn.net/pengjunlee/article/details/82979542
然后,依次修改各个节点的 mongodb.conf 配置文件,增加副本集相关配置,内容如下:
dbpath=/usr/local/mongodb-4.0.2/data
logpath=/usr/local/mongodb-4.0.2/log/mongodb.log
fork=true
logappend=true
bind_ip= # 此处填写服务器的IP
port=27017
# 设置副本集名称,在各个配置文件中,其值必须相同
replSet=rs0
配置完成之后,分别在三个节点上执行如下命令通过加载文件配置来启动MongoDB服务:
mongod -config /usr/local/mongodb-4.0.2/mongodb.conf
# 或者
mongod -f /usr/local/mongodb-4.0.2/mongodb.conf
至此,3个MongoDB实例都已经以副本集方式启动,但它们彼此之间现在还不会进行通信,仍需要进行一些配置
副本集初始化
通过 Shell 连接到任意一个MongoDB实例,执行 rs.initiate() 方法对副本集进行初始化
登录10.1.1.68 输入mongo 10.1.1.68:27017
然后输入:
conf=
{
"_id" : "rs0",
"members" : [
{ "_id" : 0, "host" : "10.1.1.68:27017" },
{ "_id" : 1, "host" : "10.1.1.69:27017" },
{ "_id" : 2, "host" : "10.1.1.70:27017" }
]
}
然后输入:
rs.initiate(conf) 如下图:
如果在执行 rs.initiate() 方法时不传入任何参数,MongoDB 将以默认的配置文档对副本集进行初始化,后续可以再通过 rs.add() 方法来向副本集中添加成员。
副本集更新
# 向副本集中添加成员
rs.add("10.1.1.71:27017")
# 从副本集中删除成员
rs.remove("10.1.1.70:27017")
# 向副本集中添加仲裁
rs.addArb("10.1.1.720:27017")
# 向副本集中添加备份节点
rs.add({"_id":3,"host":"10.1.1.73:27017","priority":0,"hidden":true})
更改副本集配置
(注: priority 值越大,优先级越高。最大值为主库。)
var conf=rs.conf()
conf.members[0].priority=6
rs.reconfig(conf)
再次查看副本集配置rs.conf() 如下图,.已经生效。
查看备份节点的复制信息
db.printSlaveReplicationInfo() , 如下图:
副本集测试
1.复制测试
在Primary 上插入一万条客户数据:for(var i=0;i<10000;i++){db.customer.insert({"name":"user"+i})}
在Secondary上查看客户数据是否已经同步:如下图,都已同步
2,故障转移测试
在主节点上,执行如下命令关闭Primary节点,查看其他2个节点的情况:
mongod --shutdown --dbpath /usr/local/mongodb-4.0.2/data
查看Primary节点关闭之前的状态
在任意其他节点上查看Primary节点关闭之后的状态
然后再次启动 10.1.1.68:27017 节点,由于其选举优先级最高,自动被选举为Primary。如下图:
副本集配置属性相关说明: rs.conf()中的属性
属性 | 含义 | 说明 |
---|---|---|
primary | 主节点(Primary)这个节点也比较容易理解。和其他数据库上的主节点一样,可以提供读写。再次不再赘述。 | |
Secondary | 辅助节点(Secondary) 辅助节点也基本上和其他类型数据库的辅助节点一样,可以充当备胎。我们在此主要讲一讲 辅助节点可以设置的几个属性 | 如上图中的secondary。 |
priority | 强制让一个节点成为Primary,可以将该节点的优先级设置成最高。 cfg = rs.conf() cfg.members[0].priority = 5 cfg.members[1].priority = 1 cfg.members[2].priority = 1 rs.reconfig(cfg) 优先级为0的节点的特点 1)不会升级为主节点。但是却可以投票。 2)此节点正常参与Primary产生的oplog的读取,进行数据备份和命令执行。 3)此节点可正常参与客户端对于数据的读取,进行担当负载均衡的工作。 4)在write concern 设置中,此节点是可见的,在决定 Priority=0在mongoDB中的解释就是一个Standby,可投票不可参选,又干活又负载。对于Priority为0节点的情况,通常作为一个standby,或由于硬件配置较差,设置为0以使用不可能成为主。 此节点在数据多中心时很有用。可以将异地的数据节点添加这种属性
| |
Hidden | 隐藏节点(Hidden) 字面上来说,隐藏。这个隐藏式对客户端的隐藏,客户端如果要读取Secondary的数据,永远无法读取Hidden节点的数据,因为设置了Hidden的这个节点对于客户端是透明的,不可见。但是,对于自己的Secondary的群体和Primary来说都是可见的,所以,Hidden依然可以投票,依然要按照oplog进行命令的复制,只是,不参与负载了。 Hidden属性的前提是必须是一个Priority=0的节点,所以会具备一些优先级=0的特点。 1)Hidden节点不能被选为主(Priority为0),并且对Driver不可见。 2)但在Hidden节点上,可做一些数据备份、离线计算的任务,不会影响复制集的服务 3)隐藏节点成员建议总是将其优先级设置为0(priority 0) 4)由于对Driver不可见,因此不会作为read preference节点,隐藏节点可以作为投票节点 5)在分片集群当中,mongos不会同隐藏节点交互。
| |
Delayed | 延迟节点(Delayed) 延迟比较容易理解,代表此节点的数据与Primary的数据有一定的迟延,通过设定一个迟延的属性来确定。 1)此节点必须是一个Priority=0且为Hidden的节点。 2)此节点虽然又迟延又Hidden,但是还是可以投票。 3)延迟单位设置为秒。
| 如上图中的slaveDelary: 延迟时间,单位秒。 |
votes | 投票节点:0:非投票节点,1:投票节点 一个副本集最多有7个投票节点,如果还有其它的节点,需要设置为非投票节点。 非投票节点拥有数据副本,但是不参与投票。另外,非投票节点,其 只有1的节点可以投票选举自己为primary节点。 | 如上上图中的votes: 1。 标识当前节点为有效投票节点,当前节点可以投票选举。 |
参考博主:pengjunlee,非常感谢。