第36章:MongoDB-集群--Replica Sets(副本集)

时间:2022-05-03 15:06:39
①副本集

副本集是一种在多台机器同步数据的进程,副本集体提供了数据冗余,扩展了数据可用性。在多台服务器保存数据可以避免因为一台服务器导致的数据丢失。也可以从硬件故障或服务中断解脱出来,利用额外的数据副本,可以从一台机器致力于灾难恢复或者备份。

mongodb副本集是一组拥有相同数据的mongodb实例,主mongodb接受所有的写操作,所有的其他实例可以接受主实例的操作以保持数据同步。主实例接受客户的写操作,副本集只能有一个主实例,因为为了维持数据一致性,只有一个实例可写,主实例的日志保存在oplog。

二级节点复制主节点的oplog然后在自己的数据副本上执行操作,二级节点是主节点数据的反射,如果主节点不可用,会选举一个新的主节点。默认读操作是在主节点进行的,但是可以指定读取首选项参数来指定读操作到副本节点。可以添加一个额外的仲裁节点(不拥有被选举权),使副本集节点保持奇数,确保可以选举出票数不同的主节点。仲裁者并不需要专用的硬件设备。仲裁者节点一直会保存仲裁者身份

........异步复制........

副本节点同步直接点操作是异步的,然而会导致副本集无法返回最新的数据给客户端程序。拥有大多数选票的副节点会被选举为主节点。

........自动故障转移........

如果主节点10s以上与其他节点失去通信,其他节点将会选举新的节点作为主节点。副本集提供了一些选项给应用程序,可以做一个成员位于不同数据中心的副本集。也可以指定成员不同的优先级来控制选举。

②副本集的结构

在集群Master故障的时候,副本集可以自动投票,选举出新的Master,并引导其余的Slave服务器连接新的Master,而这个过程对于应用是透明的。可以说MongoDB的副本集是自带故障转移功能的主从复制。

相对于传统主从模式的优势

传统的主从模式,需要手工指定集群中的 Master。如果 Master 发生故障,一般都是人工介入,指定新的 Master。 这个过程对于应用一般不是透明的,往往伴随着应用重新修改配置文件,重启应用服务器等。而 MongoDB 副本集,集群中的任何节点都可能成为 Master 节点。一旦 Master 节点故障,则会在其余节点中选举出一个新的 Master 节点。 并引导剩余节点连接到新的 Master 节点。这个过程对于应用是透明的。

第36章:MongoDB-集群--Replica Sets(副本集)

客户端连接到副本集后,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份。一旦主节点挂掉,副本节点就会选举一个新的主服务器。这一切对于应用服务器不需要关心。

心跳检测:

整个集群需要保持一定的通信才能知道哪些节点活着哪些节点挂掉。mongodb节点会向副本集中的其他节点每两秒就会发送一次pings包,如果其他节点在10秒钟之内没有返回就标示为不能访问。每个节点内部都会维护一个状态映射表,表明当前每个节点是什么角色、日志时间戳等关键信息。如果是主节点,除了维护映射表外还需要检查自己能否和集群中内大部分节点通讯,如果不能则把自己降级为secondary只读节点。

数据同步

副本集同步分为初始化同步和keep复制。初始化同步指全量从主节点同步数据,如果主节点数据量比较大同步时间会比较长。而keep复制指初始化同步过后,节点之间的实时同步一般是增量同步。初始化同步不只是在第一次才会被处罚,有以下两种情况会触发:

1)secondary第一次加入,这个是肯定的。

2)secondary落后的数据量超过了oplog的大小,这样也会被全量复制。

客户端连接到副本集后,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份。一旦主节点挂掉,副本节点就会选举一个新的主服务器。这一切对于应用服务器不需要关心。

第36章:MongoDB-集群--Replica Sets(副本集)

副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举出一位新的主服务器。

副本集包括三种节点:主节点、从节点、仲裁节点。

1)主节点负责处理客户端请求,读、写数据, 记录在其上所有操作的 oplog;

2)从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。默认情况下,从节点不支持外部读取,但可以设置    副本集的机制在于主节点出现故障的时候,余下的节点会选举出一个新的主节点,从而保证系统可以正常运行。

3)仲裁节点不复制数据,仅参与投票。由于它没有访问的压力,比较空闲,因此不容易出故障。由于副本集出现故障的时候,存活的节点必须大于副本集节点总数的一半否则无法选举主节点,或者主节点会自动降级为从节点,整个副本集变为只读。因此,增加一个不容易出故障的仲裁节点,可以增加有效选票,降低整个副本集不可用的风险。仲裁节点可多于一个。也就是说只参与投票,不接收复制的数据,也不能成为活跃节点。

官方推荐MongoDB副本节点最少为3台, 建议副本集成员为奇数,最多12个副本节点,最多7个节点参与选举。限制副本节点的数量,主要是因为一个集群中过多的副本节点,增加了复制的成本,反而拖累了集群的整体性能。 太多的副本节点参与选举,也会增加选举的时间。而官方建议奇数的节点,是为了避免脑裂的发生。

③rs辅助函数

rs是一个全局变量,其中包含了与复制相关的辅助函数,可以通过rs.help()查看。

rs.status()对应的命令是replSetGetStatus,返回的信息中,主要的字段说明:

rs.status()说明:

1:self:这个字段只会出现在运行rs.status函数的成员信息中

2:stateStr:服务器状态,状态选项在后面讲心跳的时候有

3:uptime:从成员可达一直到现在所经历的时间,单位是秒

4:optimeDate:每个成员的oplog中最后一个操作发生的时间。

注意:这里的状态是每个成员通过心跳报告上来的状态,所以optime跟实际时间可能会有几秒钟的偏差

5:lastHeartbeat:当前服务器最后一次收到其他成员心跳的时间,如果网络故障,或者是当前服务器比较繁忙,这个时间可能会是2秒钟之前

6:pingMs:心跳从当前服务器到达某个成员所花费的平均时间

7:errmsg:成员在心跳请求中返回的状态信息,通常是一些状态信息,而不是错误信息。

8:state:也表示服务器的状态,state是内部表示,而stateStr是适合阅读的表示

9:optime:和optimeDate也是一样的,只是optimeDate更适合阅读

10:syncingTo:表示当前成员正在从哪个成员处进行复制

④修改副本集配置[操作的是主节点]

1:从副本集中删除成员:rs.remove("ip:port")

2:为副本集添加成员:rs.add("ip:port");

⑤副本集中主节点的确定
是通过选举机制,要大多数的节点同意的节点才能成为主节点。
 
不设置优先级的情况下谁的数据最新谁是主
⑥成员配置选项——选举仲裁者

所谓仲裁者,就是不保存数据,专门用来投票选举主节点的副本,以解决副本个数为偶数的情况。

1:启动仲裁者和普通的副本方式一样

2:只是配置该节点的时候,设置:rs.add("ip:port" ,arbiterOnly:true),如果用rs来加入的话,应该是:rs.addArb("ip:port");

3:最多只能有一个仲裁者

4:尽量使用奇数个成员,而不是采用仲裁者

⑦成员配置选项——优先级

优先级用来表示一个成员渴望成为主节点的程度,可以在0-100之间,默认是1。

1:如果优先级为0的话,表示这个成员永远不能够成为主节点。

2:拥有最高优先级的成员会优先选举为主节点,只要它能得到"大多数"的票,并且数据是最新的,就可以了

3:一个高优先级的成员,数据又是最新的,通常会使得当前的主节点自动退位,让这个优先级高的做主节点

⑧成员配置选项——隐藏成员

对于设置为隐藏的成员,客户端不能发送请求,也不会作为复制源,通常用来做备份服务器,方式是:

1:在配置这个节点的时候,设置hidden:true

2:只有优先级为0的成员才能被隐藏

3:可以通过rs.config()或者rs.status()查看到

⑨成员配置选项——延迟备份节点

可以通过slaveDelay设置一个延迟的备份节点,以在主节点的数据不小心被破坏过后,能从备份中恢复回来。要求该备份节点的优先级为0。

⑩成员配置选项——创建索引

如果不需要备份节点与主节点拥有一样的索引,可以设置:buildIndexes:false

1:这是一个永久选项,一旦指定了,就无法恢复为创建索引的正常的节点了

2:如果要恢复,只能删掉,重新再创建节点了

3:同样要求该节点的优先级为0