MongoDB副本集
一、副本集基础
1.1 副本集概念
MongoDB副本集是由一个主节点和多个副本节点组成。主节点将数据的改变推送到副本节点上,在一定的延迟之后,每个MongoDB实例维护相同的数据。通过维护冗余的数据副本,能够实现数据的备份,读写分离和自动故障转移。
1.2 副本集使用场景
- 数据冗余,用做故障恢复使用,当发生硬件故障或者其它原因造成的宕机时,可以使用副本进行恢复。
- 读写分离,读请求会分流到所有副本上,减轻主节点的读压力。
1.3 副本集的故障转移
MongoDB副本集是主从复制的高级形式。主从复制仅仅实现了数据备份和读写分离,但是主节点一旦宕机,需要手动启动从节点进行故障转移;MongoDB副本集在主从复制基础上实现了故障转移的功能,也就是当主节点宕机时,某一台副本节点会自动提升为新主节点。
1.4 副本集相关命令
rs.initiate() #使用默认配置初始化副本集
rs.initiate(cfg) #使用配置文件cfg初始化副本集
rs.reconfig(cfg) #修改副本集配置信息
rs.status() #查看副本集状态
rs.conf() #查看副本集配置
rs.add(hostportstr) #添加新的节点
rs.addArb(hostportstr) #添加仲裁节点
rs.remove(hostportstr) #删除节点
rs.slaveOk() #允许副本节点只读,默认副本节点不允许读写
rs.isMaster() #查看哪个节点为主节点
rs.printReplicationInfo() #查看oplog大小以及oplog可用时间,可以判断系统繁忙程度
rs.printSlaveReplicationInfo() #查看复制集成员以及延迟
rs.stepDown([stepdownSecs, catchUpSecs]) #手动主从切换
rs.freeze(secs) #冻结当前节点在指定的时间内(秒)不能选举为主
rs.syncFrom(hostportstr) #管理员临时覆盖当前成员的默认同步目标。以[hostname]:[port]的形式指定要复制的成员的名称。
二、副本集成员
复制集成员最多50个。参与Primary选举投票的成员最多7个,其他成员的votes属性必须设置为0,即不参与投票。一般而言,副本集节点有3中类型,主节点(Primary)、副本节点(Secondary)、仲裁节点(Arbiter)。
2.1 主节点
和其他数据库上的主节点一样,可以提供读写服务。
2.2 副本节点
副本节点也基本上和其他类型数据库的从节点一样,可以实现备份和读写分离的作用。MongoDB的副本节点可以设置以下几个属性:
2.2.1 优先级为0的节点
优先级为0的节点的特点:
- 不会升级为主节点;但是可以投票。
- 此节点正常参与主节点产生的oplog的读取,进行数据备份和命令执行。
- 此节点可正常参与客户端对于数据的读取,进行担当负载均衡的工作。
Priority=0在mongoDB中的解释就是一个Standby,可投票不可参选,并且承担负载。对于Priority为0节点的情况,通常作为一个standby,或由于硬件配置较差,设置为0以使用不可能成为主。
2.2.2 隐藏节点
这个隐藏节点是对客户端的隐藏,客户端如果要读取副本节点的数据,永远无法读取隐藏节点的数据,因为设置了隐藏的这个节点对于客户端是透明的,不可见。但是,对于副本节点和主节点来说都是可见的,所以,隐藏节点依然可以投票,依然要按照oplog进行命令的复制,只是不参与负载了。
Hidden属性的前提是必须是一个Priority=0的节点,所以会具备一些优先级=0的特点。
- 隐藏节点不能被选为主(Priority为0),并且对Driver不可见。
- 在隐藏节点上,可做一些数据备份、离线计算的任务,不会影响复制集的服务。
- 隐藏节点成员建议总是将其优先级设置为0。
- 由于对Driver不可见,因此不会作为读节点,隐藏节点可以作为投票节点。
- 在分片集群当中,mongos不会同隐藏节点交互。
2.2.3 延迟节点
延迟节点代表此节点的数据与Primary的数据有一定的延迟,通过设定一个延迟的属性来确定。
- 此节点必须是一个Priority=0且为Hidden的节点。
- 此节点虽然又迟延又Hidden,但是还是可以投票。延迟单位设置为秒。
2.2.4 非投票节点
MongoDB一个副本集最多有7个投票节点,如果还有其它的节点,需要设置为非投票节点。非投票节点拥有数据副本,但是不参与投票。另外,非投票节点,其priority必须设置为0。
2.3 仲裁节点
没有数据副本,不会成为主节点,主要用来选举投票。当副本集的节点数据为偶数时,需要添加一个仲裁节点。仲裁节点因为没有数据,只参与投票,所以仲裁节点需要的资源很小,但是不建议将仲裁节点部署在副本集的其他节点上。
三、副本集选举机制
复制集通过rs.initiate()命令进行初始化。初始化后各个成员间开始发送心跳消息,并发起主节点选举操作,获得大多数成员投票支持的节点,会成为主节点,其余节点成为副本节点。
当复制集内投票成员数量为N,则大多数为(N/2)+1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出主节点,复制集将无法提供写服务,处于只读状态。Mongodb副本集的选举基于Bully算法,这是一种协调者竞选算法;主节点的选举受节点间心跳、优先级、最新的oplog时间等多种因素影响。
触发选举条件:
- 初始化一个副本集时;
- 从库不能连接到主库(默认超过10s,可通过heartbeatTimeoutSecs参数控制),由从库发起选举;
- 主库放弃primary角色,比如执行rs.stepDown(30)命令;
四、副本集同步机制
副本集中数据同步过程:主节点写入数据,副本节点通过读取主节点的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。简单的说就是:当主节点完成数据操作后,副本节点会做出一系列的动作保证数据的同步:
- 检查自己local库的oplog.rs集合找出最近的时间戳。
- 检查主节点local库oplog.rs集合,找出大于此时间戳的记录。
- 将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。
副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设定:--oplogSize 1000,单位是M。
PS:在副本集的环境中,要是所有的Secondary节点都宕机了,只剩下Primary节点。最后Primary节点会变成Secondary节点,不能提供服务。
五、总结
本文详细介绍了MongoDB副本集的基本概念、特性,副本集成员以及选举、同步特性。