第39章:MongoDB-集群--Replica Sets(副本集)---副本集基本原理

①操作日志oplog

Oplog是主节点的local数据库中的一个固定集合,按顺序记录了主节点的每一次写操作,MongoDB的复制功能是使用oplog来实现的,备份节点通过查询这个集合就可以知道需要进行哪些数据的复制了。

每个备份节点也都维护着自己的oplog,记录着每次从主节点复制数据的操作。这样每个节点都可以作为数据的同步源提供给其他成员使用。

注意几点:

1:由于是先复制数据,再写日志,因此可能会出现重复的复制操作,这个没有关系,MongoDB会处理这种情况,多次执行Oplog中同一个操作与执行一次是一样的。

2:oplog的大小是固定的,它只能保存特定数量的操作日志,如果多次大批量的执行操作,oplog很快就会被填满,oplog的大小,可以通过mongod的--plogSize来指定

3:oplog的内容,在local数据库的oplog.rs集合里面   db.oplog.rs.find();

②初始化同步

当副本集中的一个成员启动的时候,它就会检查自身状态,然后到集群中检查是否需要同步,以及从哪儿同步,并进行数据的复制,这个过程就称为初始化同步。

 

大致步骤如下:

 

1:记录前的准备工作:选择一个成员作为同步源,在local.me中为自己创建一个标识符,删除所有已存在的数据库,以全新的状态开始同步

2:从数据源把所有数据复制到本地

3:写oplog,把所有复制中的操作写入oplog

4:把上一步oplog同步中的操作记录下来

5:此时数据应该和数据源一致了,可以开始创建索引了

6:如果当前节点的数据仍然远远落后于数据源,那么oplog会将创建索引期间的所有操作同步过来

7:完成初始化同步后,切换到普通同步状态,也就可以作为备份节点使用了

③处理陈旧数据

如果备份节点远远落后于同步源的数据,那么这个节点上的数据就是成旧数据。

通常的处理办法是:让主节点使用比较大的oplog,以保存足够多的操作日志,可以让备份节点慢慢来同步操作。

④心跳

为了维护集合的最新状态,每个成员每隔2秒会向其他成员发送一个心跳请求,用于检查每个成员的状态。

 

常见状态如下:

1:主节点、备份节点

2:STARTUP:成员刚启动时处于这个状态,加载完副本集配置后,进入STARTUP2

3:STARTUP2:整个初始化同步过程都处于这个状态

4:RECOVERING:表明成员运转正常,但暂时还不能处理读取请求

5:ARBITER:仲裁者始终处于这个状态

 

系统出问题的话,会处于如下状态

1:DOWN:成员不可到达,有可能成员还是在正常运行,也有可能挂了

2:UNKNOWN:标识一个成员无法到达其他所有的成员

3:REMOVED:成员被移出副本集

4:ROLLBACK:成员正在进行数据回滚

5:FATAL:成员出现了致命的错误,也不再尝试恢复正常

⑤回滚

回滚的时候,会把受到影响的文档,保存到数据目录下的rollback目录中,文件名为集合名.bson,基本步骤是:

1:判断是否需要回滚,典型就是副本记录和主记录不一致了

2:在两个oplog中寻找最后一个共同的点

3:然后副本回滚到这个共同的点

4:副本再从主节点同步数据回来

注意:

如果要回滚的数据很多,比如大于300M,或者需要操作30分钟以上,回滚就会失败。如果回滚失败的话,就需要重新同步了。

副本集的工作流程

在 MongoDB 副本集中,主节点负责处理客户端的读写请求,备份节点则负责映射主节点的 数据。备份节点的工作原理过程可以大致描述为,备份节点定期轮询主节点上的数据操作,然后对 自己的数据副本进行这些操作,从而保证跟主节点的数据同步。至于主节点上的所有 数据库状态改变 的操作,都会存放在一张特定的系统表中。备份节点则是根据这些数据进行自己的数据更新。

 

 

oplog

上面提到的数据库状态改变的操作,称为 oplog(operation log,主节点操作记录)。oplog 存储在 local 数据库的"oplog.rs"表中。副本集中备份节点异步的从主节点同步 oplog,然后重新 执行它记录的操作,以此达到了数据同步的作用。

关于 oplog 有几个注意的地方:

1)oplog 只记录改变数据库状态的操作

2)存储在 oplog 中的操作并不是和主节点执行的操作完全一样,例如"$inc"操作就会转化为"$set"操作

3)oplog 存储在固定集合中(capped collection),当 oplog 的数量超过 oplogSize,新的操作就会覆盖就的操作

 

 

数据同步

在副本集中,有两种数据同步方式:

1)initial sync(初始化):这个过程发生在当副本集中创建一个新的数据库或其中某个节点刚从宕机中恢复,或者向副本集中添加新的成员的时候,默认的,副本集中的节点会从离 它最近的节点复制 oplog 来同步数据,这个最近的节点可以是 primary 也可以是拥有最新 oplog 副本的 secondary 节点。该操作一般会重新初始化备份节点,开销较大。

2)replication(复制):在初始化后这个操作会一直持续的进行着,以保持各个 secondary 节点之间的数据同步。

 

 

initial sync

当遇到无法同步的问题时,只能使用以下两种方式进行 initial sync 了

1)第一种方式就是停止该节点,然后删除目录中的文件,重新启动该节点。这样,这个节 点就会执行 initial sync注意:通过这种方式,sync 的时间是根据数据量大小的,如果数据量过大,sync 时间就会很长同时会有很多网络传输,可能会影响其他节点的工作

2)第二种方式,停止该节点,然后删除目录中的文件,找一个比较新的节点,然后把该节点目 录中的文件拷贝到要 sync 的节点目录中

通过上面两种方式中的一种,都可以重新恢复"port=33333"的节点。不在进行截图了。

 

 

副本集管理

1)查看oplog的信息 通过"db.printReplicationInfo()"命令可以查看 oplog 的信息

  字段说明:

  configured oplog size: oplog 文件大小

  log length start to end:     oplog 日志的启用时间段

  oplog first event time:      第一个事务日志的产生时间

  oplog last event time:       最后一个事务日志的产生时间

  now:                         现在的时间

 

2)查看 slave 状态 通过"db.printSlaveReplicationInfo()"可以查看 slave 的同步状态当插入一条新的数据,然后重新检查 slave 状态时,就会发现 sync 时间更新了

副本集数据执行过程

Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。简单的说就是:

 

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

1)检查自己local库的oplog.rs集合找出最近的时间戳。

2)检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。

3)将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。

 

 

副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。

 

注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

 

副本集选举的过程和注意点

Mongodb副本集选举采用的是Bully算法,这是一种协调者(主节点)竞选算法,主要思想是集群的每个成员都可以声明它是主节点并通知其他节点。别的节点可以选择接受这个声称或是拒绝并进入主节点竞争,被其他所有节点接受的节点才能成为主节点。节点按照一些属性来判断谁应该胜出,这个属性可以是一个静态 ID,也可以是更新的度量像最近一次事务ID(最新的节点会胜出)

 

副本集的选举过程大致如下:

1)得到每个服务器节点的最后操作时间戳。每个 mongodb 都有 oplog 机制会记录本机的操作,方便和主服 务器进行对比数据是否同步还可以用于错误恢复。

2)如果集群中大部分服务器 down 机了,保留活着的节点都为 secondary 状态并停止,不选举了。

3)如果集群中选举出来的主节点或者所有从节点最后一次同步时间看起来很旧了,停止选举等待人来操作。

4)如果上面都没有问题就选择最后操作时间戳最新(保证数据是最新的)的服务器节点作为主节点。

 

 

 

副本集选举的特点:

选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半(建议副本集成员为奇数。最多12个副本节点,最多7个节点参与选举)如果已经小于一半了所有节点保持只读状态。集合中的成员一定要有大部分成员(即超过一半数量)是保持正常在线状态,3个成员的副本集,需要至少2个从属节点是正常状态。如果一个从属节点挂掉,那么当主节点down掉 产生故障切换时,由于副本集中只有一个节点是正常的,少于一半,则选举失败。4个成员的副本集,则需要3个成员是正常状态(先关闭一个从属节点,然后再关闭主节点,产生故障切换,此时副本集中只有2个节点正常,则无法成功选举出新主节点)。

MongoDB 同步延迟问题

当你的用户抱怨修改过的信息不改变,删除掉的数据还在显示,你掐指一算,估计是数据库主从不同步。与其他提供数据同步的数据库一样,MongoDB 也会遇到同步延迟的问题,在MongoDB的Replica Sets模式中,同步延迟也经常是困扰使用者的一个大问题。

 

 

什么是同步延迟?

首先,要出现同步延迟,必然是在有数据同步的场合,在 MongoDB 中,有两种数据冗余方式,一种是Master-Slave 模式,一种是Replica Sets模式。这两个模式本质上都是在一个节点上执行写操作, 另外的节点将主节点上的写操作同步到自己这边再进行执行。在MongoDB中,所有写操作都会产生 oplog,oplog 是每修改一条数据都会生成一条,如果你采用一个批量 update 命令更新了 N 多条数据, 那么抱歉,oplog 会有很多条,而不是一条。所以同步延迟就是写操作在主节点上执行完后,从节点还没有把 oplog 拿过来再执行一次。而这个写操作的量越大,主节点与从节点的差别也就越大,同步延迟也就越大了。

 

 

同步延迟带来的问题

首先,同步操作通常有两个效果,一是读写分离,将读操作放到从节点上来执行,从而减少主节点的 压力。对于大多数场景来说,读多写少是基本特性,所以这一点是很有用的。另一个作用是数据备份, 同一个写操作除了在主节点执行之外,在从节点上也同样执行,这样我们就有多份同样的数据,一旦 主节点的数据因为各种天灾人祸无法恢复的时候,我们至少还有从节点可以依赖。但是主从延迟问题 可能会对上面两个效果都产生不好的影响。

 

 

如果主从延迟过大,主节点上会有很多数据更改没有同步到从节点上。这时候如果主节点故障,就有 两种情况:

1)主节点故障并且无法恢复,如果应用上又无法忍受这部分数据的丢失,我们就得想各种办法将这部 数据更改找回来,再写入到从节点中去。可以想象,即使是有可能,那这也绝对是一件非常恶心的活。

2)主节点能够恢复,但是需要花的时间比较长,这种情况如果应用能忍受,我们可以直接让从节点提 供服务,只是对用户来说,有一段时间的数据丢失了,而如果应用不能接受数据的不一致,那么就只能下线整个业务,等主节点恢复后再提供服务了。

 

 

如果你只有一个从节点,当主从延迟过大时,由于主节点只保存最近的一部分 oplog,可能会导致从 节点青黄不接,不得不进行 resync 操作,全量从主节点同步数据。带来的问题是:当从节点全量同步的时候,实际只有主节点保存了完整的数据,这时候如果主节点故障,很可能全 部数据都丢掉了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Lucky-stars/p/10555510.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值