美文网首页
【mongoDB】mongoDB 数据同步和自动故障转移原理

【mongoDB】mongoDB 数据同步和自动故障转移原理

作者: Bogon | 来源:发表于2022-09-11 14:54 被阅读0次

一、数据同步的原理

当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:
1、检查自己local库的oplog.rs集合找出最近的时间戳
2、检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录
3、将找到的记录插入到自己的oplog.rs集合中,并执行这些操作

PRIMARY> rs.status()

{
    "set" : "test",
    "date" : ISODate("2015-07-02T02:38:15Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 2,
            "name" : "192.168.91.144:27017",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 1678,
            "lastHeartbeat" : ISODate("2015-07-02T02:38:14Z"),
            "lastHeartbeatRecv" : ISODate("2015-07-02T02:38:14Z"),
            "pingMs" : 1
        },
        {
            "_id" : 1,
            "name" : "192.168.91.135:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 1678,
            "optime" : Timestamp(1435803750, 1),
            "optimeDate" : ISODate("2015-07-02T02:22:30Z"),
            "lastHeartbeat" : ISODate("2015-07-02T02:38:14Z"),
            "lastHeartbeatRecv" : ISODate("2015-07-02T02:38:13Z"),
            "pingMs" : 1,
            "syncingTo" : "192.168.91.148:27017"
        },
        {
            "_id" : 0,
            "name" : "192.168.91.148:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1698,
            "optime" : Timestamp(1435803750, 1),
            "optimeDate" : ISODate("2015-07-02T02:22:30Z"),
            "electionTime" : Timestamp(1435803023, 1),
            "electionDate" : ISODate("2015-07-02T02:10:23Z"),
            "self" : true
        }
    ],
    "ok" : 1
}
myState:1表示primary
state:1表示primary;7表示arbiter
uptime:成员的在线时间
lastHeartbeat:当前实例到远端最近一次成功接收到心跳包的时间
pingMs:本实例到远端路由包的来回时间
optime:读取oplog.rs集合中本实例最近一次的更改时间

二、mongoDB数据同步的过程:

1:拉取同步节点的oplog。例如:Secondary节点拉去Primary节点的oplog。

2:将拉取的oplog写入到自己的oplog中。例如:Secondary节点从Primary拉去的oplog写入到自己的oplog。

3:请求下一个oplog同步到哪里。例如:Secondary会请求Primary节点同步到哪里了

Secondary节点同步到哪了?

1:Primary节点插入一条数据,同时会把该数据写入到Primary的oplog中,并且记录一个时间戳

2:db.runCommand({getlasterror:1,w:2}) 在Primary节点被调用时,Primary就完成了写入操作,等待其他非仲裁节点来同步数据

3:Secondary节点查询Primary的oplog并且拉取oplog

4:Secondary根据时间戳应用oplog

5:Secondary请求大于本身oplog时间戳的oplog

6:Primary更新时间戳

初始化同步:

1:新增加的节点或者oplog同步时候被覆写的时候都会进行初始化同步

2:从源节点取最新的oplog time,标记为start

3:从源节点克隆所有的数据到目标节点

4:在目标节点建立索引

5:取目标节点最新的oplog time,标记为minValid

6:在目标节点执行start到minValid的oplog(应该是复制过来还没有执行的oplog,没有完成最终一致性的那部分,就是一个oplog replay的过程)

7:成为正常成员

Initial Sync
 
Initial sync copies all the data from one member of the replica set to another member. A member uses initial sync when the member has no data, such as when the member is new, or when the member has data but is missing a history of the set’s replication.
 
When you perform an initial sync, MongoDB:
 
1:Clones all databases. To clone, the mongod queries every collection in each source database and inserts all data into its own copies of these collections. At this time, _id indexes are also built. The clone process only copies valid data, omitting invalid documents.

2:Applies all changes to the data set. Using the oplog from the source, the mongod updates its data set to reflect the current state of the replica set.

3:Builds all indexes on all collections (except _id indexes, which were already completed).
When the mongod finishes building all index builds, the member can transition to a normal state, i.e. secondary.


从哪个成员来同步数据(Who to sync from)?

MongoDB初始化同步数据的时候,可能从主节点同步,也可能是从从节点同步,根据最近的原则,选择最邻近节点去同步数据。(基于ping值)

同时也可以用任选以下一种方式指定从哪个节点来同步数据:

db.adminCommand( { replSetSyncFrom: "[hostname]:[port]" } )
rs.syncFrom("[hostname]:[port]")

新同步过来的数据并不能查看,Secondary默认不可读不可写。
如果需要查看要执行rs.slaveOk(),则当前shell连接上可以查看,后续的其他连接还是不可读不可写。

Primary写处理

master负责接收写请求,具体的流程为:

如果开启journal功能,则先将写请求记录到journal中,然后批量执行,同时将操作记录到oplog中

如果未开启journal功能,则对每个写请求进行单独操作,然后写入oplog

注:oplog是幂等的,当有累加操作inc时,会记录成set操作,从而无论重复执行多少次操作获得的结果都是一样的

从节点同步

如果是一个新的从节点,首先先从master的数据库文件进行复制,同时记录起始时间;当从节点从master的复制完成后,会根据复制的起始时间开始追oplog,进而与master进行同步。

初始化同步完成后的Secondaty定期从Primary的oplog中获取最新的操作,然后对自己的数据副本执行这些操作,从而保证Secondaty的数据与Primary最终一致性。

注意:当slave同步的速度赶不上master更新的速度时,oplog会因为追加了过多的操作而发生将旧记录覆盖掉,这样slave可能无法保证同步所有的数据,这时,slave会开始从头重新同步。

三、 mongoDB故障自动转移

image.png image.png image.png

mongoDB通过lastHeartbeat来实现自动转移。

mongod实例每隔2s就会向其他成员发送一个心跳包,并且通过rs.status()中返回的成员的health来判断成员的状态。

当主节点与集合中的其他成员的通信electionTimeoutMillis时间超过配置的时间段(默认为10秒)时,合格的secondary节点将要求选举,以提名自己为新的主节点。

如果primary节点不可用了,那么复制集中的所有secondary节点都会触发一次选举操作,选出新的primary节点。

群集尝试完成新主数据库的选择并恢复正常操作。

如果secondary节点有多个,则会选举拥有最新oplog时间戳记录的或者有较高权限的节点成为primary。

注意:如果secondary停止时间过长,导致primary节点的oplog内容被循环写覆盖掉了,则需要手动同步secondary节点。

节点类型



任何时间,集群中只有一个活跃节点,其他的都是备份节点。
有几种不同类型的节点可以存在与副本集中:

standard 标准节点
这是常规节点,它存储一份完整的数据副本,参与选举投票有可能成为活跃节点。

passive 被动结点
存储了完整的数据副本,参与投票,不能成为活跃节点,如延时节点。

arbiter 仲裁者
仲裁者只能参与投票,不接收复制的数据,也不能成为活跃节点。 

节点优先级

每个参与节点(非仲裁)有优先权,优先权按照优先值从大到小,默认优先级为1,可以是0-1000(含)。

在节点配置中修改priority键,来配置标准节点或者被动节点:

> members.push({"_id":3,"host":"xx.xx.xx.xx:17017","priority":40})

"arbiterOnly"键可以指定仲裁节点:

members.push({"_id":4,"host":"xx.xx.xx.xx:27017","arbiterOnly":true})

备份节点会从活跃节点抽取oplog,并执行操作,就像活跃备份系统中的备份服务器一样。
活跃节点也会写操作到自己的本地oplog,oplog中的操作包含严格递增的序号,这个序号来判定数据的时效性,所以节点之家的时间同步非常重要!

选举策略

如果活跃节点出现故障,其余节点会选一个新的活跃节点。
选举过程可以由任何非活跃节点发起,新的活跃节点由副本集中的大多数选举产生。
其中仲裁节点也参与选举,避免出现僵局。
新的活跃节点将是优先级最高的节点,优先级相同则数据较新的节点获胜。

不论活跃节点何时变化,新的活跃节点的数据就被假定为系统的最新数据,对其他节点(原活跃节点)的操作都会回滚,即便是之前的活跃节点已经恢复工作了。
为了完成回滚,所有节点连接新的活跃节点后重新同步。这些节点会查看自己的oplog,找出活跃节点没有的操作,然后向活跃节点请求这些操作影响的文档最新副本。
正在执行重新同步的节点被视为恢复中,在完成这个过程之前不能成为活跃节点的候选者。

四、参考

mongoDB中文手册/复写
https://mongodb.net.cn/manual/replication/#replication-flow-control

数据库命令 > 复制命令 > replSetSyncFrom
https://mongodb.net.cn/manual/reference/command/replSetSyncFrom

Replica Set Data Synchronization
https://www.mongodb.com/docs/manual/core/replica-set-sync/#replica-set-initial-sync-source-selection

mongoDB 副本集添加新的节点
https://blog.csdn.net/csdnhsh/article/details/116333686

相关文章

  • 【mongoDB】mongoDB 数据同步和自动故障转移原理

    一、数据同步的原理 当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:1、检...

  • MongoDB副本集

    MongoDB有主从复制和副本集两种复制模式,主从复制最大的问题就是无法自动故障转移,MongoDB副本集则解决了...

  • MongoDB实战

    MongoDB的数据模型和持久化策略和设计目标——是提高读写吞吐量 ,在易于伸缩的同时还能进行自动故障转移。 为了...

  • mongodb安装配置

    简介 **MongoDB ** 开源,高性能的NoSQL数据库;支持索引、集群、复制和故障转移、各种语言的驱动程序...

  • 搭建一个MongoDB副本集系统

    在任何服务系统中,要提供系统服务高可用,必须要解决单点故障及实现故障自动转移。mongodb的副本集提供了这样的功...

  • mongoDB

    mongoDB基础 MongoDB简介 一个开源文档数据库,提供高性能、高可用性和自动扩展的功能。MongoDB ...

  • MongoDB - 安装、启动、停止

    一、包说明 MongoDB官方源中包含以下几个依赖包:mongodb-org: MongoDB元数据包,安装时自动...

  • mongodb复制集群

    Mongodb的复制功能: Mongodb的复制架构: Mongo的数据同步类型: 主从复制选项: 选举机制: m...

  • 使用mongo shell管理MongoDB

    1 MongoDB简介 mongodb是开源的文档数据库,提供了高性能,高可用性和自动伸缩的数据库服务。mongo...

  • mogondb

    Mongodb副本集副本集是什么 – MongoDB 复制是将数据同步在多个服务器的过程。 – 复制提供了数据的冗...

网友评论

      本文标题:【mongoDB】mongoDB 数据同步和自动故障转移原理

      本文链接:https://www.haomeiwen.com/subject/pooxortx.html