zoukankan      html  css  js  c++  java
  • 关于MongoDb Replica Set的故障转移集群——理论篇

    自从10 gen用Replica Set取代Master/Slave方案后生活其实已经容易多了,但是真正实施起来还是会发现各种各样的小问题,如果不小心一样会栽跟头。

    在跟Replica Set血拼几天之后,笔者写下以下的血泪史,供大家参考。

    背景知识

    Replica Set的目标是取代Master/Slave方式成为MongoDB新的集群组织方式,目前已经适合生产环境使用。

    原理上二者差不多,都是通过local库中的oplog存放操作日志,再重做日志而把操作复制到新的实例上。

    按照官方说法,Replica Set提供了更稳定的运行效果,操作更容易,并且提供自动故障恢复特性。相比之下,Master/Slave集群能够胜出的只有“能够容纳更多实例”这一条。原因是前者为了保证实例之间能够互相了解生存状态,需要两两交换心跳(每2秒1次,可以从日志中看到)。这就要求构成一个n(n-1)/2条路径的网络,使得集群额外增加了通讯负担,特别是在集群成员数量巨大的时候将会造成先显著的影响(当然通常情况下是不需要把集群做到这种规模的)。作为交换,Replica Set则够提供了新的故障转移特性。

    故障转移介绍

    故障转移是通过不同结点之间的角色切换达到的。角色分为三种:Primary,Secondary和Arbiter。顾名思义,Primary是主结点,可进行写入操作。操作日志从Primary向各个Secondary同步并重做达到数据复制的目的。当Primary出现故障时,集群成员会选举其中一个Secondary成为新的Primary。而Arbiter则是一个只参与投票的结点,不复制实际的内容。

    影响选举进行的因素包括:

    1. 心跳

    心跳每2秒进行一次,如果在10秒(5次)内没有收到一个结点的心跳,则认为这个结点已经死亡,需要选举新的Primary结点。

    2. priority配置

    每个结点都具备Priority设置,默认为1。可以通过以下命令查看

    rs.conf()

    可能的情况下,集群结点总是选举优先级最高的结点成为新的Primary。优先级0是特殊配置,这样的结点不会成为选举的候选结点(如Arbiter结点)。

    当集群中出现了优先级比当前Primary更高的活跃结点时,会发生重新选举,而无论当前Primary是否存活。所以如果之前死亡的高优先级Primary结点恢复工作,并同步完所有操作日志,会马上发生选举使它重新成为Primary。

    这在某些情况下会造成问题,因为Primary角色会在不同结点之间来回切换,而切换过程中集群会有短暂的不可用时间。把所有结点的优先级设置为相同则可以保证选举发生的次数更少,但这也不能说一定是件好事。总之没有最好的方案,只有最合适的方案。

    3. optime(最后同步时间)

    一个结点的最后同步时间必须是最接近Primary的,才有参与选举的资格,否则即使priority高也不行。

    所以可以想象在群集中可能发生这样的状况:

    Primary A死亡后,Secondary B具有更高的优先级,但同步时间比不上Secondary C。因此C会被优先提升为Primary。此后B从C处同步了最近的操作日志,成为了具备最高优先级,并且操作日志也最新的结点,因此B会成为新的Primary,C降级为Secondary。

    当然在同一个网络中,这种情况发生的可能性不高。异地机房则更有可能发生。

    4. 投票

    一个要成为Primary的结点必须得到集群中大多数成员选票。这里的多数成员并不是指的集群成员的数量,而是指参与投票的成员数量。

    所以在3个成员的集群中,一个Primary死亡后,另外两个Secondary会产生出一个新的Primary。而如果2个成员死亡,剩下的一个会保持Secondary身份,因为得不到其他成员的投票。如果剩下的成员是Primary,则它会降级为Secondary。

    要注意对于其他成员是否死亡的判断是相对的,一个结点只能判断死亡的结点对自己已经不可见,但是否真的死亡并不确定。也可能是自己从网络中脱离而造成自己对所有人都不可见。MongoDB必须保证任何时候任何情况都只能有一个Primary,因此对于升级的判断也是保守的,宁可不升级为Primary,也不可以让多于一个Secondary升级为Primary(会造成不可逆转的错误)。

    要小心集群只剩一个成员的情况,它极有可能变成一个只读的集群,这对生产环境来说是灾难性的。以后的篇幅会讲如何处理这种情况。

    5. 网络划分

    如果Primary死亡的时候没有一个Secondary得到足够的选票,则集群会变为只读的。因此多数结点应该位于同一个数据中心,避免因为数据中心间的网络故障造成集群变为只读。

    从以上问题可以了解到Arbiter的必要性,它的存在可以解决极端情况下集群成员无法投票决定新的Primary的问题。

    下一篇将会讲解Replica Set的实际操作情况。

    参考文献:MongoDb Manual

  • 相关阅读:
    将Nginx添加到windows服务中
    springboot使用redis管理session
    GIT常用命令
    阻止360、谷歌浏览器表单自动填充
    谈谈对Spring IOC的理解
    同一个Nginx服务器同一端口配置多个代理服务
    LeetCode 653. Two Sum IV
    109. Convert Sorted List to Binary Search Tree(根据有序链表构造平衡的二叉查找树)
    108. Convert Sorted Array to Binary Search Tree(从有序数组中构造平衡的BST)
    LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)
  • 原文地址:https://www.cnblogs.com/yaoxing/p/mongodb-replica-set.html
Copyright © 2011-2022 走看看