复制集高可用选举机制

在上一章介绍了MongoDB的架构,复制集的架构直接影响着故障切换时的结果。为了能够有效的故障切换,请确保至少有一个节点能够顺利升职为主节点。保证在拥有核心业务系统的数据中心中拥有复制集中多数节点。让多数能够参与投票的节点或是所有可以成为主节点的节点在这个数据中心中。但是,如果节点间网络不通将会让其无法参与并成为多数节点。

如果你有了解一些常用的高可用软件,那么就会很清楚高可用中的选举机制了。我们先来看看复制集中选举的机制,了解几个概念。

一、大多数原则

1)什么是大多数原则?

当前复制集中,存活节点的数量必须大于节点总数的1/2,这样才能触发选举,否则当从节点挂掉时主节点会降级为从节点;当主节点挂掉时从节点也不会升为主节点。

2)怎么样才算大多数原则?

我们可以看下面这个图。

由于MongoDB的大多数原则,当复制集节点为3个时,主节点允许发生故障且剩余两个节点由于满足大多数原则所以会自动选出一台新的主节点。如果新选出来的主节点又发送故障那么不好意思此时最后一个从节点并不会成为主节点。

当复制集节点为4个时,主节点允许发送故障且剩余三个节点由于满足大多数原则所以会自动选出一台新的主节点。如果新选出来的主节点又发送故障那么不好意思此时剩余两个节点由于不满足大多数原则所以此复制集就不会有主节点了。

PS:由上述两个实例的说明,可以看出当复制集中的节点数位相邻的奇数和偶尔时,服务器的故障利用率则是相同的。所以当有偶数个节点时,此时可以做一个投票节点(此节点不暂用资源所以可以在其他正在提供服务的机器上运行)

3)为什么会有大多数原则?

对于这个问题,初学者一般都持有疑问,感觉这个设计是个什么鬼?复制集是我们管理的,为什么不可以让管理员来设置谁做主,谁做从,然后当主节点挂掉之后允许那个从节点去接替主节点的工作。确实这个方法在有些高可用软件中就是这么指定的,如Linux中的keepalived、还有如CISCO的HSRP机制都是这么规定的。而到了Mongodb中就变成了选举管理员不可控。我们来看这个一种情况,如下图。

上图共有7个节点,DC1有4个节点并且主节点在DC1,而DC2有三个节点都是从节点。由于在两个机房之间的网络通信有很多不确定性,并且复制集节点之间主要靠心跳信息来确认对方是否存活是否重新选举,默认心跳信息从节点2秒传送一次给主节点,如果在10秒内对方没有回应那么就认为主节点故障从而触发选举。那么问题来了,比如说现在的7个节点的复制集已经稳定了,当网络出现大延迟的时候,DC1跟DC2之间已经无法正常传送心跳信息了,此时会发生什么情况?

DC1由于有一个主节点了,所以它的一主三从不会发生变化,但是DC2由于探测不到DC1的主节点从而三个从节点触发选举,会在三个节点中选出一个主节点来,此时一个复制集中出现了两个主节点就会导致数据不一致性。当MongoDB使用了大多数原则时当两个机房之间在遇到网络延迟时就不会发生出现两个主节点的情况了。当DC1探测不到DC2时,DC1由于有一个主节点了,所以它的一主三从不会发生变化。而DC2中的三台从节点由于不满足大多数原则(存活主机小于总主机数的1/2)所以不会产生选举,所以三个节点不会有是变化。看完分析之后不知道你明白了没有。

二、选举触发条件

1)  主节点故障

2)  主节点网络不可达(默认心跳信息为10秒)

3)  人工干预(rs.stepDown(600))

三、影响选举的因素

1)复制集心跳检测

Mongodb复制集成员之间的联系跟所有高可用所用的机制相同,那就是“心跳监测”机制,默认从节点会2秒一次地向主节点发出心跳监测请求,如果对方在10秒之内没有回应的话,就会认为节点故障。

当主节点不可达时,复制集会做一个判断,其他成员是否对主节点也不可达。如果都不可达那么复制集就会产生新的选举争取选出一台主节点从新为应用程序提供服务。

其他节点不可达时,

2)成员优先级

一个复制集稳定的初选后,选举算法将作出努力尝试把具有最高优先级的可用从节点呼叫出出来选举。比如,如果在复制集中主节点的优先级大于默认值1,那么当主节点宕机重新恢复后成为从节点但由于优先级大于现有的主节点从而会重新取得主节点状态。当priority为0时表示永远没有资格成为主节点,且priority的值为0也是设置隐藏节点及延迟节点的前提条件。

3)网络隔离

网络隔离影响了选举中多数选票的结构,如果主节点不可用了,且每个相互隔离的网络中都没有多数选票的出现,那么复制集将不会选举出新的主节点。复制集将变为只读的。为了避免这种情况的出现,我们需要将多数节点置于主数据中心,少数节点放于其他数据中心。

4)Replication Election Protocol

3.2新版功能,MongoDB版本1的复制协议减少复制集切换时间和加速同时初选的检测。新的复制集默认情况下使用版本1,旧的MongoDB使用版本0是以前版本的协议。

复制集高可用选举过程

复制集高可用选举过程大概有四个阶段,下图介绍了复制集选举的过程:

第一阶段:心跳检测

前面也说过,心跳检测是高可用的一个必要技术手段,心跳检测就是让每个成员通过心跳请求了解到当前集群中其他节点的状态。比如当前集群中谁是主节点,当前集群中存活的数量是否满足2/1原则。所以说每个节点通过2秒钟发送一个心跳检测来尽可能了解集群状态。

第二阶段:维护主节点备选列表

什么是主节点备选列表,也就是说当需要进行选举的时候,选举出来一个新的主节点。那么谁能够有资格被选举成新的主节点呢?这个主节点选举也算是非常复杂的了,要经过一系列复杂的判断之后才能够进入主节点备选列表,下图详解介绍了一个节点进入主节点备选列表需要判断哪些条件?

接下来就要进入主节点检测环节

注意,这里说的是主节点备选列表,还不是被选为主节点。

第三阶段:选举准备

在选举准备阶段,又需要一系列判断,可以说是通过九九八十一难才能允许别人向自己投票。

当一个在主节点列表中的节点自身能够满足上述的几个条件后,就开始调用自选方法,选举自己成为新的主节点,但真正允许其他节点向自己投票它又需要经过下列一些自我检测才能最后敲定允许其他节点投票自己。如下图:

第四阶段:投票

最后就是投票了,在经历过投票之后就可以选出一个新的主节点了,如下图:

在最后一步投票结束后,参与选举的节点首先会进行检查自己是否收到反对票。什么时候会出现反对票呢?

第一就是自己的版本比其他数据库要低时会收到反对票;

第二就是当前复制集中已经选举出了一个主节点时会收到反对票;

第三在参与选举过程中有其他节点priority比它高时会收到反对票;

一旦收到反对票,此节点就会减10000票,投票可以通过vote设定一个节点可以投的票数,但默认都是1票。基本上就是一票否决制的,如果收到反对票就需要等待一段时间了。

然后检查是否有相同票数的,如果有相同票数的就需要重新选举了,重新来过。这样就是为什么前面多次提到MongoDB复制集的节点最好是基数个而不是偶数个了,就是为了避免相同票数的出现从而导致重新投票。

如果集群中没有相同票数的,接着还要检查自己的票数是否过半,如果过半就可以被选为主节点了。

终于完了,也是艰难啊,其实MongoDB在真正实现选举的机制比上面说的要麻烦的多。

MongoDB复制集高可用选举机制(三)的更多相关文章

  1. 生产环境下搭建mongodb复制集高可用环境(python)

    环境描述:有三台ubuntu服务器,,每台服务器上已经有mongodb实例.创建3个mongo2.4的新实例,分别作为三个复制集节点,同时保证了当前单节点环境的稳定 3台服务器都已经有单个mongo实 ...

  2. mongodb副本集高可用架构

    一.简介 Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点. Mongodb Driver(客户端)的所有数据都写入Primary,Sec ...

  3. MongoDB 3.4 高可用集群搭建(二)replica set 副本集

    转自:http://www.lanceyan.com/tech/mongodb/mongodb_repset1.html 在上一篇文章<MongoDB 3.4 高可用集群搭建(一):主从模式&g ...

  4. MongoDB学习4:MongoDB复制集机制和原理,搭建复制集

    1.复制集的作用   1.1 MongoDB复制集的主要意义在于实现服务高可用   1.2 它的实现依赖于两个方面的功能:    · 数据写入时将数据迅速复制到另一个独立节点上    · 在接收写入的 ...

  5. MongoDB 2.6复制集单节点部署(三)

    MongoDB在单节点中也可以做复制集,但是仅限于测试实验,最大的好处就是部署方便快速,可以随便添加新节点,节省资源.在这里我使用的是MongoDB 2.6版本进行复制集实验(但MongoDB配置文件 ...

  6. Raft与MongoDB复制集协议比较

    在一文搞懂raft算法一文中,从raft论文出发,详细介绍了raft的工作流程以及对特殊情况的处理.但算法.协议这种偏抽象的东西,仅仅看论文还是比较难以掌握的,需要看看在工业界的具体实现.本文关注Mo ...

  7. mongodb复制集Replica Set使用简介

    MongoDB高可用 对于MongoDB,可以支持使用单机模式提供服务,但是在实际的生产环境中,单机模式将面临很大的风险,一旦这个数据库服务出现问题,就会导致线上的服务出现错误甚至崩溃.因此,在实际生 ...

  8. MongoDB 复制集节点增加移除及节点属性配置

    复制集(replica Set)或者副本集是MongoDB的核心高可用特性之一,它基于主节点的oplog日志持续传送到辅助节点,并重放得以实现主从节点一致.再结合心跳机制,当感知到主节点不可访问或宕机 ...

  9. MongoDB复制集概念架构浅析

    一.复制集的作用 (1) 高可用 防止设备(服务器.网络)故障. 提供自动failover 功能. 技术来保证数 (2) 灾难恢复 当发生故障时,可以从其他节点恢复. (3) 功能隔离 用于分析.报表 ...

随机推荐

  1. css3 - target

    通过CSS3伪元素target,我们可以实现拉风琴 源码 <!DOCTYPE HTML> <html lang="en-US"> <head> ...

  2. Codeforces Beta Round #1 A. Theatre Square

    从今天開始.就要在Codeforces里有一个新的開始了,貌似任务非常重的说~~ Codeforces专题我将会记录全部通过的题目,事实上仅仅要通过的题目都是水题啊!. 题目大意: 依照要求计算须要多 ...

  3. asp .net 为图片添加图片水印 .

    首先写好一个写入图片水印的类,先创建一个ImageWriter类库   (该类中有包含枚举类型和方法) using System; using System.Collections.Generic; ...

  4. 为什么应使用 Node.js

    为什么应使用 Node.js JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样,现在我们也可以在服务器上运行 JavaScrip ...

  5. SGPIO

    http://en.wikipedia.org/wiki/SGPIO SGPIO From Wikipedia, the free encyclopedia   Serial General Purp ...

  6. 网页编程-django前传

    1.js正则表达式  http://www.cnblogs.com/wupeiqi/articles/5602773.html test  - 判断字符串是否符合规定的正则 正则表达式: rep = ...

  7. python--多种程序分析(2)

    1.文件操作有哪些模式?请简述各模式的作用 r模式只读  w模式只写 a模式只添加   r+可读可写  w+可写可读  a+可读可添加   rb  二进制只读  wb 二进制只写   ab 二进制添加 ...

  8. Learning English From Android Source Code:2 Ampersand

    这一次想把标点符号的英语表达总结一下,这些单词非常重要但easy被我们忽视.以我的经验,还是多认识几个.以备不时之需. 以下从"标点符号"開始: punctuation [英][ˌ ...

  9. MYSQL 5.6修改密码

    忘记了超级用户root密码的时候怎么办呢? 1. 修改配置文件跳过密码 (1)编辑mysql主配置文件my.cnf # vim /etc/my.cnf 在[mysqld] 字段下添加参数 skip-g ...

  10. 误用了 react-scripts eject 命令

    react 小白编程 由于使用 create-react-app 脚手架构建项目的时候,会给几个命令用 其中一个命令吸引了我的注意力  yarn eject,因为构建完成后特别提示说“你不会想要用到这 ...