一   复制集的高可用性简介

      复制集通过故障自动切换来实现高可用性,当主节点出现故障的时候,从节点可以通过选举成为主节点,而这个过程在大多数当情况下是自动进行的,不需要手动干预。在某些情况下,故障自动切换需要数据回滚。

      复制集部署的方式(复制集成员数量、物理因素,如带宽 复制集成员地理位置等)可能会影响自动切换的效率。为了提高自动切换的效率,我们应该将复制集的大多数成员放到一个核心的数据中心来进行管理,在复制集里多放几个从节点,当主节点失效的时候,不但保证有可用的从节点可以使用,而且还可以防止因网络故障的发生,隔离大多数复制集成员的通信。

   自动故障切换主要包括两大过程:选举 和 回滚

   选举在复制集的操作中扮演着非常重要的作用,选举过程是要花费时间的,在选举过程中,复制集是没有主节点的,整个复制集是无法接受客户端的请求,所以MongoDB尽量避免选举的进行。那么什么情况下才会进行选举呢?
选举的发生:当主节点不可用的时候;复制集初始化(initiating)的时候.

二  影响选举的因素

   1.心跳(Heartbeats)
       心跳:复制集成员每隔两秒互相发送一次心跳请求包(其是就是ping对方),如果在10秒钟内没有收到对方成员对心跳包回复的话,就认为它出现了故障。

   2.优先级比较(
Priority Comparisons
)
       成员的优先级会影响到选举的过程,成员们会优先将自己的票投给优先级高的成员。
       拥有0优先级的成员不会被选为主节点,因为他们没有被选举权,
不会被投票
       只要当前的主节点拥有最高的优先级且其操作日志条目内容也是最新的,那就不会进行选举。这时
如果有一个更高优先级的成员加入且其操作日志所记录最新操作时间和当前主节点记录的时间相差小于10秒的时候,这时就会进行选举,给高优先级节点提供一个成为主节点的
机会。
 

    3.操作时间(
Optime)
      操作时间指的是一个成员最后一次执行操作日志时的时间。如果一个成员比其他的成员操作时间都最新(most recent)的话,就有可能被选为主节点。

     4.连通性(
Connections)
      复制集中的一个成员只有和大多数成员保持联通,得到大多数人的投票才可以成为主节点,否则会自动降级成为从节点。

      例如:对于一个拥有三个成员的复制集,每个成员都可以投票,那么只有其中的两个人可以保持联通的话,复制集就可以进行一次选举。如果其中两个变的不可用,剩下的那个节点如果是从节点的话,那么它仍然还是一个从节点,因为它不能和其他的成员保持连通。同样的道理如果该节点是主节点的话,也会自动的降级成为从节点,因为它不能和别的成员保持连通,失去了成为主节点的资格.这样的话该复制集就变成只读了。

     5.网络分区(
Network Partitions
      由于网络分区,如果一个主节点不可用的话,其余
大多数
从节点又不能连通的话,复制集就无法进行选举。所以尽量将大部分复制集成员放到一个数据中心中,而将一小部分放到另外一个。

三 选举的过程

1.心跳检测

       假设我们有三个节点的replica set:X,Y和Z节点。在replica sets结构中,这三个节点每2秒会各自向其它两个节点发送一个心跳检测请求。比如X节点向Y和Z节点各发送了一个心跳检测请求,在正常情况下,Y、Z会返回一个包含自身信息的回复包,回复包中主要包括了下面一些信息:它们现在是什么角色(primary 还是 secondary),他们是否有资格成为成为 primary,以及他们当前时戳等等。
       X节点在收到回复包后,会用这些信息更新自己的一个状态映射表,更新的内容包括:是否有新的节点加入或有老的节点宕掉,这个请求的网络传输时间等等。
       
而当X节点的映射表发生了变化,那X会进行下面的逻辑判断:如果X是 primary,而另外一个节点出现故障,那么它会确认自己是否还能和集群中大多数节点进行通信,如果不能与大多数节点通信,那么他会把自己从 primary 降级为 secondary。(注意:在replica sets中,primary 必须能够和集群中的大多数节点进行通信,以免发生网络断开形成两个或多个节点群各自为政的情况,这样会影响到数据的一致性。)

 2.关于降级


       在节点从 primary 降级为 secondary 的过程中,会有一些问题出现。在 MongoDB 中,写操作默认是通过 fire-and-forget(发射即不管,相当于自动制导炸弹) 的模式来进行的,也就是说写操作通常不关心是否成功,发完请求后客户端就认为成功了。但如果这时候 primary 进行降级操作,那么客户端并不知道这时候 primary 已经降级成为 secondary 了,客户端可能还会将后续的写操作发送给这个节点。这时候刚刚降级的这个 secondary 可以发送一个包说“我已经不是 primary 了”,但是我们上面说过了,客户端根本就无视你这个包。所以客户端根本不知道这次写入已经失败了。
     
      对于这个问题,你可能会说”那我们每次都使用安全写入不就行了“(安全写入意思是说等待服务器返回成功后客户端才认为写成功了),但是很明显,这非常不靠谱。所以我们的做法是,在一个 primary 降级成为 secondary 后,它会将原来的所有连接关闭。这样客户端在下一次写入的时候就会出现 socket 错误。而客户端在发现这个错误之后,就会重新向集群获取新的 primary 的地址,并将后续的写操作都往新的服务器上写入。

 3.选举

我们回头再来看心跳监测请求:如果X是一个 secondary,那么X会定时检测是否需要选举自己成为 primary,即使自己的状态映射表没有发生改变。其检测内容包括:是否集群中有其它节点认为自己是 primary?X节点自己是否已经是 primary?X节点自己是否有资格成为 primary?如果这三个问题中的任何一个回答是否定的,那么X节点就不会试图把自己变成primary。(也就是说,只有当X节点是一个能够当 primary 的secondary,并且其它节点都不是primary时,X才会发起选举并选自己为primary)

       而当X发现现在需要一个 primary 并且自己又正好可以充当时,它就会发起一轮选举:X节点会向Y、Z节点各发起一个请求包,告知他们”我认为我可以接管 primary 的角色,你们觉得怎么样?当Y和Z收到上面的请求包时,他们会进行下面几项检测:他们是否已经知道集群中有一个 primary了?他们自己的数据是否比X节点更新?是否有其它节点的数据比X节点更新?如果上面条件有任何一个满足,那么他们都会认为X不够资格成为 primary,他们会发送一个返回包告知X说”停止选举!“。而如果三个条件都不成立,也就是说他们认为目前集群中确实没有 primary,并且X的数据又是最新的,那么他们会发送返回包告知X说”没问题“。

     
如果X收到”停止选举!“的返回,那么他会马上停止选举并保持自己为 sencondary 状态。
     如果X收到所有其它节点都返回说”没问题“,那么他会进入选举过程的第二阶段。

      在第二阶段中,X会向其它节点发送一个包,说”我宣布我已经是 primary 了“。这时候,Y和Z节点再进行一些最终的确认:上面的判断过的所有条件是否依然表明X可以做 primary,如果确实如此,那么他们会在本轮 primary 选举中向X出赞成票。并且他们投完赞成票后,30秒内不会再做其它投票决定。
       
     上面是说如果第二次确认还是通过的情况,那么如果最终确认没有通过呢。他们会投一个反对票,反对X成为 primary,如果有反对票产生,那么这一轮选举就失败了。X还是保持 secondary 的身份。
       
下面我们假设一种情况,如果Y给X投了赞成票,而Z给X投了反对票。那这时候Y由于投了赞成票,它在30秒内不能再进行投票。所以如果这时候Z发起选举想让自己成为 primary,那么Z这时候必须要获得X的赞成票。因为这时候Y不能投票,为了获取多数票,Z必须获得X的赞成票。
所以投票的规则是这样的:如果没有人投反对票,并且赞成票的比例过半,那么本轮选举对象就能够成为 primary。 


注:1.引发投票选举的事件:
               复制集进行初始化的时候
               当从节点失去与主节点的联系,号召大家来选举投票

               主节点进行降级
        2.引发节点进行降级的事件:
               当主节点收到replSetStepDown 命令的时候
               如果一个从节点拥有资格成为主节点,有比主节点更高优先级
               当主节点和大多数从节点无法进行连通的时候
         3.   当主节点变得不可用的时候会自动关闭和客户端得所有连接,这样可以保持客户端和数据库得数据一致性。
        4.Priortity0 成员不会触发选举操作,即使它们无法连接到主节点


 

MongoDB 复制集(二) 选举 自动故障切换的更多相关文章

  1. mongodb 复制集

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

  2. MongoDB复制集高可用选举机制(三)

    复制集高可用选举机制 在上一章介绍了MongoDB的架构,复制集的架构直接影响着故障切换时的结果.为了能够有效的故障切换,请确保至少有一个节点能够顺利升职为主节点.保证在拥有核心业务系统的数据中心中拥 ...

  3. MongoDB复制集的工作原理介绍(二)

    复制集工作原理 1)数据复制原理 开启复制集后,主节点会在 local 库下生成一个集合叫 oplog.rs,这是一个有限集合,也就是大小是固定的.其中记录的是整个mongod实例一段时间内数据库的所 ...

  4. MongoDB 复制集 (一) 成员介绍

       一 MongoDB 复制集简介          MongoDB的复制机制主要分为两种:          Master-Slave    (主从复制)      这个已经不建议使用       ...

  5. MongoDB复制集原理、环境配置及基本测试详解

    一.MongoDB复制集概述 MongoDB复制集实现了冗余备份和故障转移两大功能,这样能保证数据库的高可用性.在生产环境,复制集至少包括三个节点,其中一个必须为主节点,一个从节点,一个仲裁节点.其中 ...

  6. MongoDB复制集原理

    版权声明:本文由孔德雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/136 来源:腾云阁 https://www.qclo ...

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

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

  8. MongoDB复制集成员及架构介绍(一)

    MongoDB复制集介绍 MongoDB支持在多个机器中通过异步复制达到提供了冗余,增加了数据的可用性.MongoDB有两种类型的复制,第一种是同于MySQL的主从复制模式(MongoDB已不再推荐此 ...

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

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

随机推荐

  1. php5.3 不支持 session_register() 此函数已启用的解决方法

    php从5.2.x升级到5.3.2.出来问题了.有些原来能用的程序报错了,Deprecated: Function session_register() is deprecated php从5.2.x ...

  2. [python]类与类中的列表

    最近在用类中的列表时出现一件怪事 实例2中的列表,竟然有实例1中的数据. 查了半天发现是list的append方法的问题. 将全部的list.append(value) 换成 list = list ...

  3. cursor_sharing

    CURSOR_SHARING Property Description Parameter type String Syntax CURSOR_SHARING = { EXACT | FORCE } ...

  4. 常见内部函数----Python

    In [10]: test = [1,2,"yes"] ---append(x) 追加到链尾 In [11]: test.append(1) In [12]: test Out[1 ...

  5. 版本控制工具git入门

    版本控制工具的历史 不说了,放张图 两者的区别:集中式需要一个中心服务器放置最新的文件,需要联网操作.分布式可以再不联网的情况下操作,前提要拥有版本库 git安装  略 github注册 略 如何在g ...

  6. The Promise of Deep Learning

    The Promise of Deep Learning By Yoshua Bengio Humans have long dreamed of creating machines that thi ...

  7. draw9patch超详细教程

    这篇文章是android开发人员的必备知识,内容摘选自网络,友我为大家整理和总结,不求完美,但是有用. 视频教程地址:http://player.youku.com/player.php/sid/XM ...

  8. C51 的编程规范

    编程首要是要考虑程序的可行性,然后是可读性.可移植性.健壮性以及可测试性.这是总则.但是很多人忽略了可读性.可移植性和健壮性(可调试的方法可能歌不相同),这是不对的. 1.当项目比较大时,最好分模块编 ...

  9. android Service开机启动及debug

    开机启动一个service需要做的工作如下: 1.开发一个receiver用于接收系统广播: public class BootReceiver extends BroadcastReceiver { ...

  10. 关于MIUI6下使用Widget调用Toast的一个问题

    编写了一个Widget程序,在继承AppWidgetProvider类中调用Toast,发现如下问题: 在小米2,MIUI Version:MIUI5.6.4|Beta, Android Versio ...