golang数据库 MongoDB 复制(10)

Golang 2023/04/23 MongoDB, Golang

复制的简介

1.1 复制的作用

集群部署多个Mongo数据库服务器,同时利用Mongo的复制功能,可以自动将数据同步到这些多台服务器中,设置好策略即可免去繁琐的人工操作。

当然,多台机器中通过异步复制还可以达到故障转移和冗余数据备份的目的。

为什么要复制:

  • 数据备份

  • 数据灾难恢复

  • 读写分离

  • 高(24* 7)数据可用性

  • 无宕机维护

  • 副本集对应用程序是透明

1.2 复制方案

MongoDB提供了两种复制方案:

  • 主从复制(Master-Slave):3.2版后已移除主从复制,早期mongo复制集群不能超过11个节点

  • 复制集(ReplicaSets):3.2版本后的默认复制方案

主从复制和复制集都使用了共同的复制机制:只在一个节点上进行写操作,写入的数据会异步的同步到所有节点。

主从复制至少有一个主节点,以及一个或者多个从节点,假如A是主节点,负责处理客户端请求,那么其余的都是从节点,负责复制主节点上的数据。节点常见的搭配方式为:一主一从、一主多从。主节点记录在其上的所有操作,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。

主从复制有一个极大的弊端:如果主节点断电或者出现故障,那么整个Mongo集群就不能正常运作了。副本集就是为了应对该复制方案而出现的新方式。

复制集就是为了解决主从复制的容灾问题,可以将副本集理解为具备自动故障恢复功能的主从集群。与主从复制不同,复制集没有固定的主节点,整个集群会选举出一个主节点,当主节点不能工作时,又会另外选举其他节点为主节点。复制集中总会有一个活跃节点(Primary)和一个或多个备份节点(Secondary)。推荐3个以上(因为2个节点不具备故障切换能力,因为故障切换需要仲裁节点)。

复制集的整个流程都是自动化的,只需要为复制集指定有哪些服务器作为节点,驱动程序就会自动去连接服务器。

1.3 复制集的密码

单例的MongoDB中只需要--auth参数即可开启安全认证,在复制集中需要设置KeyFile之后才能生效。

复制集认证的思路是:账户、密码、KeyFile,KeyFile需要各个副本集服务启动时间加载而且KeyFile文件的内容必须一致。

注意:连接复制集成员的KeyFile和启动mongos进程的KeyFile文件内容必须一样,且是base64位编码,不能有等号,文件权限也必须是x00(即不能分配任何权限给group成员和other成员)。

启动参数:

--keyFile /data/replset/key/r1

二 复制集操作

接下来的操作需要打开多个终端窗口,而且可能会连接多台linux主机,

step1:使用如下格式启动mongod,注意replSet(属于哪个复制集)的名称是一致的
mongod --port 27017 --dbpath ~/Desktop/t1 --logpath ~/Desktop/t1log --replSet rs0            
mongod --port 27018 --dbpath ~/Desktop/t2 --logpath ~/Desktop/t1log --replSet rs0

step2:连接其中任意服务器
mongo --host 192.168.196.128 --port 27017
rs.initiate()               # 初始化,然后查看当前状态
rs.status()

step3:添加复本集,这个操作也可以可以在initiate中传入一个json配置            
rs.add(\'192.168.196.128:27018\')
rs.status()
传入json配置的方式:
var conf = {
    _id:"rs0",
    memebers:[
        {_id:0,host:192.168.196.128:27018},     # id为0的默认为primary
        {_id:1,host:*****}
    ]
}
rs.initiate(conf)

step4:连接第二个mongo服务
mongo --host 192.168.196.128 --port 27018
执行插入数据
use test1
for(i=0;i<10;i++){db.t1.insert({_id:i})}
db.t1.find()

step5:在从服务器中插查询 如果在从服务器上进行读操作,需要设置rs.slaveOk()
rs.slaveOk()
db.t1.find()

删除从节点
rs.remove(\'192.168.196.128:27018\')
关闭主服务器后,再重新启动,会发现原来的从服务器变为了从服务器,新启动的服务器(原来的从服务器)变为了从服务器

三 复制集原理

副本集要完成数据的复制和修复,需要2个基础机制:

  • oplog:operation log,操作日志,负责复制

  • heartbeat:心跳,负责监控节点健康,并触发故障转移

3.1 oplog操作日志

副本集中只有主节点才会接受客户端的写入操作,也就是说从节点需要监控主节点的写入,并能模仿主节点的写入操作。

oplog是一个固定集合,位于每个复制节点的local数据库里,记录了所有对数据的变更操作(写入操作)。oplog每个文档都代表主节点上执行的一个操作。

复制步骤:

  • 1 每当客户端向主节点写入数据,就会自动向主节点的oplog添加一个文档

  • 2 一旦写入操作文档被复制到某个从节点上,从节点就会执行重现这个写入操作,然后从节点的oplog也会保存一条关于写入的操作记录。

  • 3 从节点也会定期更新:将自己的oplog里最后一条时间戳,与查询到的主节点上oplog最后一条时间戳对比,依据此来更新

注意:从节点第一次启动时,会对主节点的数据进行一次完整的同步。

我们必须要考虑一种情况:
从节点复制主节点的oplog并执行,这个操作是异步的,对主节点来说是异步的,也就是主节点不需要等到从节点执行完同样的操作就可以继续下一个写入操作了。当写入操作太快,从节点还没更新完,主节点的oplog是固定集合已经轮滚一圈了,复制就会停下,从节点需要做完整的复制。为了避免这种情况,需要尽量保证主节点的oplog足够大,能够存放相当长时间的操作记录。
还有一种办法是:暂时阻塞主节点的操作,我们称之为阻塞复制。在主节点使用getLastError命令加参数w来确保数据的同步性。比如把w参数设置为N的10次方,运行getLastError命令后,主节点进入阻塞,知道N-1个从节点复制了最新的写入操作为止。但是这样会造成明显的写操作减慢,一般w的值都在2或者3即可。

3.2 心跳机制

心跳机制用户发现故障后进行自动选举和故障转移。默认情况下,每个复制集成员每2秒ping一次其他成员,用来检查健康状况。

如果有节点出现无法ping通的现象,那么

  • 1 判断该节点是猪节点还是从节点

  • 2.1 如果故障的是从节点,不做处理,等待从节点重新上线

  • 2.2 如果故障的是主节点,重新选举主节点

还有一种场景:如果主节点突然失去了其他大多数节点的心跳,主节点会将自己降级为从节点,这样可以防止因为网络原因,主节点与其他节点断开连接,从节点重新选举产生了新的主节点,而原来的主节点没有降级,会出现2个主节点,这时写入会产生混乱。

3.3 仲裁节点

Mongo在3.0版本后,复制集成员提升到了50个,对选举流程也做了优化,提出了仲裁节点(Arbitter)的概念。仲裁节点是本之际中的一个实例,不保存数据,只负责选举时的投票。

仲裁节点使用最小的资源,并且不要求硬件设备,不容易宕机,建议不把Arbiter部署在同一个数据集节点中,否则入股数据集节点服务器挂了,仲裁节点也会失效,就没有起到作用,仲裁节点也可以多于1个。

MongoDB的投票需要超过半数的节点投票给同一节点才能生效,把该节点提升为主节点,在某些情况,尤其是偶数节点投票时,如果两个节点投票数一致,会导致无法决定出主节点,卡在了投票环节,仲裁节点此时会被邀请出来判决。

MongoDB官方推荐集群节点数为奇数。在3.0后,一个副本集可以有50个成员,但是只有7个投票成员

3.4 选举机制

集群遇到故障,在选举出主节点之前,整个集群服务是只读的,不能执行写入操作。

非仲裁节点都有一个优先级配置,范围是0-100,越大的值越能成为主节点,默认情况是1,如果是0则不能成为主节点。

选举机制会尽最大努力使优先级最高的节点成为主节点,即使副本集中已经选举出了比较稳定的但是优先级较低的节点,该节点也只能短暂的作为主节点运行一段时间,不能一直作为主节点。后续仍然会继续发起选举,直到选举出优先级最高的节点成为主节点为止。

四 复制集的运维

4.1 复制集回滚丢失数据

当复制集中一个成员发生变化修改oplog后,其他成员也将按照oplog来执行,如果负责处理新数据的节点在出错后恢复运行,它将会被回滚到最后一个oplog公共点,但是丢失的新数据已经被Mongo从数据库中转移并存放到了目录rollback中等待恢复。如果不知道该特性,你很可能认为数据丢失了。

所以当有成员从出错中恢复后,需要检查该目录。


本文地址:https://www.stayed.cn/item/391

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。