MongoDB副本集

副本集架构

对于mongodb来说,数据库高可用是通过副本集架构实现的,一个副本集由一个主节点和若干个从节点所组成。

客户端通过数据库主节点写入数据后,由从节点进行复制同步,这样所有从节点都会拥有这些业务数据的副本,当主节点发生故障而变得不可用时,从节点能主动发起选举并产生新的主节点进行接管,此时,客户端仍然能继续进行访问,这保证了业务的连续性。

MongoDB选举介绍

mongodb的副本集选举、复制机制是基于Raft协议的。Raft协议的选举机制中leader必须通过大多数节点投票才能产生。我们假设副本集的投票成员数量为N,则大多数为N/2+1。当副本集内存活的成员数量不足大多数时,整个副本集将无法选举除主节点,此时无法提供写服务,这些节点都将处于只读状态。此外,如果希望避免平票结果的产生,最好使用奇数个节点成员,比如3个或5个。当然,mongodb副本集的实现中,对于平票问题已经提供了解决方案:

  • 为选举定时器增加少量的随机时间偏差,这样避免各个节点 在同一时刻发起选举,提高成功率。
  • 使用仲裁者角色,该角色不做数据复制,也不承担读写业务,仅仅用来投票。

此外,在一个mongodb副本集中,最多只能有50个成员,而参与投票的成员最多只能有7个。这是因为一旦过多成员参与数据复制、投票过程,将会带来更多可靠性方面的问题。

mongodb为副本集成员提供了多种角色,具体如下:

  • Primary:主节点,其接收所有的写请求,然后把修改同步到所有从节点。一个副本集只能有一个主节点,当主节点"挂掉"之后,其他节点会重新选举出一个主节点。
  • Secondary:从节点,与主节点保持同样的数据集。当主节点"挂掉"时,参与竞选主节点。
  • Arbiter:仲裁者节点,该节点只参与投票,不能被选为主节点,并且不从主节点中同步数据。当节点宕机导致副本集无法选出主节点时,可以给副本集添加一个仲裁节点,这样仍然可以选出主节点。仲裁者节点本身不存储数据,是非常轻量级的服务。当副本集成员为偶数时,最好加入一个仲裁者节点,以提升副本集的可用性。
  • Priority0:优先级为0的节点,该节点永远不会被选举为主节点,也不会主动发起选举。通常,在跨机房方式下部署副本集可以使用该特性。假设使用了机房a和机房b,由于主要业务与机房a更近,则可以将机房b的副本集成员priority设置为0,这样主节点就一定会时a机房的成员。
  • Hidden:隐藏节点,具备Priority0的特性,即不能被选为主节点,同时该节点对客户端不可见。由于隐藏节点不会接收业务访问,因此可通过隐藏节点做一些数据备份、离线计算的任务,这并不会影响整个副本集。
  • Delayed:延迟节点,必须同时具备隐藏节点和Priority0的特性,并且其数据落后于主节点一段时间,该时间是可配置的。由于延迟节点的数据比主节点落后一段时间,当错误或者无效的数据写入主节点时,可通过延迟节点的数据来恢复到之前的时间点。
  • Vote0:无投票权的节点,必须同时设定为Priority0节点。由于一个副本集中最多只能有7个投票成员,隐藏多出来的成员则必须将其vote属性设置为0,即这些成员将无法参与投票。

一般来说,成员能否成为主节点,主要受某些因素的影响,这包括节点之间的心跳,节点的优先级,以及OpLog时间戳。而触发一次选举,通常会来自下面的场景:

  • 初始化一个副本集时。
  • 从节点在一段时间内发现不了主节点(默认10s超时),由从节点发起选举。
  • 主节点放弃自己的角色,比如执行rs.stepDown命令。

副本集模式

  1. PSS模式
    由一个主节点和两个从节点所组成。
  2. PSA模式
    由一个主节点、一个从节点和一个仲裁者节点所组成。其中,仲裁者节点不存储数据副本,也不提供业务的读写操作,仅仅影响选举投票。
  3. PSH模式
    由一个主节点、一个从节点和一个隐藏节点所组成。隐藏节点对业务不可见,同时无法被选举为主节点。一般利用隐藏节点来执行数据备份任务,可以避免备份对业务性能产生影响。

实时复制

oplog复制

在副本集架构中,主节点与从节点之间是通过oplog来同步数据的,这里的oplog是一个特殊的固定集合,当主节点上的一个写操作完成后,回向oplog集合写入一条对应的日志,而从节点则通过这个oplog不断拉取新的日志,在本地进行回收以达到数据同步的目的。我们可以将oplog看作缓冲队列,那么整个复制过程就是一个典型的"生产者-消费者"模式的应用。

复制延迟

由于oplog集合是有固定大小的,因此存放在里面的oplog随时可能会被新的记录冲掉。如果从节点复制不够快,就无法跟上主节点的步伐,从而产生复制延迟问题。一旦从节点的延迟过大,则随时会发生复制断裂的风险,这意味着从节点的optime(最新一条同步记录)已经被主节点老化掉,从节点无法进行数据同步,因此我们可以采取如下操作:

  • 增加oplog的容量大小(replication.oplogSizeMB),并保持对复制窗口的监视。
  • 通过一些扩展手段降低主节点的写入速度。
  • 优化从节点之间的网络。
  • 避免字段使用太大的数组

自动故障转移

在一个PSS架构的副本集,主节点除了与两个从节点执行数据复制,3个节点之间还会通过心跳感知彼此的存活。一旦主节点发生故障后,从节点将在某个周期内检测到主节点处于不可达的状态,此后将由其中一个从节点事先发起选举并最终成为新的主节点。

一个影响检测机制的因素是心跳,在副本集组建完成后,各个成员节点会开启定时器,持续向其他成员发起心跳,这里涉及到的参数为heartbeatIntervalMillis,即心跳间隔时间,默认值是2s。如果心跳成功,则会持续以2s的频率继续发起心跳;如果心跳失败,则会立即充实心跳,一直到心跳恢复成功。

另一个重要的因素是选举超时检测,一次心跳检测失败并不会立即触发重新选举。实际上,除了心跳,成员界定是还会启动一个选举超时检测定时器,该定时器默认以10s的间隔执行,具体可以通过electionTimeoutMillis参数指定:

  • 如果心跳响应成功,则取消上一次的electionTimeout调度(保证不会发起选举),并发起新一轮的electionTimeout调度。
  • 如果心跳响应迟迟不能成功,那么electionTimeout任务就会被触发,进而导致从节点发起选举并成为新的主节点。

因此,在electionTimeout任务中触发选举必须要满足以下条件:

  1. 当前节点是从节点。
  2. 当前节点具备选举权限。
  3. 在检测周期内仍然没有与主节点心跳成功。

在mongodb的实现中,选举超时检测的周期要略大于electionTimeoutMillis设定。该周期会加入一个随机偏移量,大约在10~11.5s,如此的设计是为了错开多个从节点主动选举的时间,提升成功率。因此,我们在实现业务的时候,需要考虑因主节点切换而导致的超时问题,例如添加读写超时重试的功能以及如果使用了mongodb3.6以及以上版本的驱动,则可以通过开启retryWrite来降低影响。

搭建副本集

具体读者可以参考下面这篇博客:MongoDB基础入门

相关推荐
史迪仔01122 小时前
【SQL】SQL多表查询
数据库·sql
Quz2 小时前
MySQL:修改数据库默认存储目录与数据迁移
数据库·mysql
Familyism2 小时前
Redis
数据库·redis·缓存
隔壁老登2 小时前
查询hive指定数据库下所有表的建表语句并生成数据字典
数据库·hive·hadoop
sekaii3 小时前
ReDistribution plan细节
linux·服务器·数据库
焱焱枫3 小时前
自适应SQL计划管理(Adaptive SQL Plan Management)在Oracle 12c中的应用
数据库·sql·oracle
2301_793069823 小时前
Spring Boot +SQL项目优化策略,GraphQL和SQL 区别,Spring JDBC 等原理辨析(万字长文+代码)
java·数据库·spring boot·sql·jdbc·orm
hhw1991124 小时前
spring boot知识点5
java·数据库·spring boot
ITPUB-微风4 小时前
功能开关聚合对象实践:提升金融领域的高可用性
网络·数据库·金融
去看日出4 小时前
Linux(centos)系统安装部署MySQL8.0数据库(GLIBC版本)
linux·数据库·centos