zoukankan      html  css  js  c++  java
  • MongoDB 复制机制

    一、复制原理

    MongoDB的复制功能是使用操作日志oplog实现的,oplog包含主节点(Master)的每一次写操作,oplog是local本地数据库中的一个数据集合,其它非主节点(Secondary)通过读取主节点的oplog集合中的记录同步到对应的集合,然后再写入到自身的local数据库的oplog集合中。每个节点都维护着自己的oplog,记录着每一次从主节点复制数据的操作。这样每个成员都可以作为同步源提供给其它成员使用。

    注意:需要注意Secondary节点同步数据的顺序是先同步数据,然后再写入oplog;这点和mysql的机制不同。但是每个节点oplog中记录的同步数据是完全一致的,所以也不担心被执行多次。

     

    二、oplog集合

    1.insert操作

    /* 1 */
    
    {
    
        "ts" : Timestamp(1520580648, 1),
        "t" : NumberLong(20),
        "h" : NumberLong(-8701728013874689868),
        "v" : 2,
        "op" : "i",
        "ns" : "test.person",
        "ui" : UUID("782befd9-80ae-4a2c-86ae-33a147e7c948"),
        "wall" : ISODate("2018-03-09T07:30:48.120Z"),
        "o" : {
            "_id" : ObjectId("5aa2382f7239a98c7e679114"),
            "name" : "zhang"
        }
    }

    2.update操作

    /* 1 */
    
    {
        "ts" : Timestamp(1520584444, 2),
        "t" : NumberLong(20),
        "h" : NumberLong(7151217369265341585),
        "v" : 2,
        "op" : "u",
        "ns" : "test.person",
        "ui" : UUID("782befd9-80ae-4a2c-86ae-33a147e7c948"),
        "o2" : {
            "_id" : ObjectId("5aa2382f7239a98c7e679114")
        },
        "wall" : ISODate("2018-03-09T08:34:04.777Z"),
        "o" : {
            "$v" : 1,
            "$set" : {
                "name" : "wang"
            }
        }
    }
    • ts: 操作时间,当前timestamp + 计数器,计数器每秒都被重置
    • h:操作的全局唯一标识
    • v:oplog版本信息
    • op:操作类型:
    1. i:插入操作
    2. u:更新操作
    3. d:删除操作
    4. c:执行命令(如createDatabase,dropDatabase)
    5. n:空操作,特殊用途
    • ns:操作针对的集合
    • ui:
    • o:操作内容,如果是更新操作
    • o2:操作查询条件,仅update操作包含该字段
    • wall:记录的时间戳。

    3.查询oplog集合

    db.oplog.rs.find(
    
    {"op":{$in:["i","u","d"]}}
    
    )
    
    .sort({"wall":-1});

    三、初始化同步

    1.选择一个成员作为同步源,在local.me中创建标识符;删除已存在的数据库。

    2.将同步源的所有数据复制到本地。所有的操作都被集合到oplog中。

    3.将第一个oplog同步中的操作记录下来。

    4.创建相关索引,如果集合比较大该过程可能会花费很长的时间。

    5.将创建索引过程中同步源增加的记录同步过来。

    6.同步完成,修改节点状态为SECONDARY

    四、心跳

    每个成员每隔两秒钟就会向其它成员发送一个心跳请求,心跳的请求信息量非常的小,用于检查每个成员的状态。

    心跳最主要的功能之一就是让主节点知道自己是否满足集合“大多数”的条件。如果主节点不再得到“大多数”服务器的支持,它就会退位变成备份节点。

    成员状态

    Number

    Name

    State Description

    0

    STARTUP

    Not yet an active member of any set. All members start up in this state. The mongod parses the replica set configuration document while inSTARTUP.

    1

    PRIMARY

    The member in state primary is the only member that can accept write operations. Eligible to vote.

    2

    SECONDARY

    A member in state secondary is replicating the data store. Eligible to vote.

    3

    RECOVERING

    Members either perform startup self-checks, or transition from completing a rollback or resync. Eligible to vote.

    5

    STARTUP2

    The member has joined the set and is running an initial sync.

    6

    UNKNOWN

    The member’s state, as seen from another member of the set, is not yet known.

    7

    ARBITER

    Arbiters do not replicate data and exist solely to participate in elections.

    8

    DOWN

    The member, as seen from another member of the set, is unreachable.

    9

    ROLLBACK

    This member is actively performing a rollback. Data is not available for reads.

    10

    REMOVED

    This member was once in a replica set but was subsequently removed.

    五、选举

    当一个成员无法到达主节点时,它就会申请被选举为主节点。希望被选举为主节点的成员会向它能到达的所有成员发送通知。如果这个成员不符合候选人的要求,其它成员可能会知道相关原因:这个成员的数据落后于副本集,或者已经有一个运行中的主节点(希望被选举为主节点的成员无法到达这个主节点)。在这些情况下,其它成员不会允许进行选举。

    如果没有其它成员反对,其他成员就会对这个成员进行选举投票,如果满足副本集中“大多数”赞成票,它就被选举成功,转换成为主节点。否则选举失败仍然处于备份节点状态,之后还可以再次申请被选举为主节点。而主节点会一直主节点状态,除非它由于不再满足“大多数”的要求或者宕机而退位,另外副本集被重新配置也会导致主节点退位。

    在网络良好的情况下,同时投票服务器也正常运行那么选举过程会很快,由于节点之间的互ping是每隔2S,所以如果有主节点不可用那么2S之内就会有成员发现,然后就会立即开始选举,整个过程正常只会花费几毫秒。如果存在网络问题或者服务器过载响应缓慢都有可能触发选举。在这种情况下,心跳会在最多10S之后超时。如果选举打成平局,每个成员都需要等待30S才能开始下一次选举,所以如果发生太多错误的情况下选举可能会花费几分钟的时间。

    六、回滚

     

    一般情况下跨数据中心复制要比同数据中心复制慢。

    上图的两个数据中心之间出现网络故障,DC1最后的操作是126,DC2最后的操作是125;DC1的126操作还没有被复制到DC2;由于采取的是多数节点的投票机制,DC2数据中心的副本满足“大多数”节点的要求(一共5台服务器,3台服务器即可超过半数投票)。因此其中一台服务器会被选举成为新的主节点,这个主节点会继续后续的写操作。假设在DC1的网络恢复之前DC2已经操作到了130。

    DC1

    123

    124

    125

    126

    DC2

    123

    124

    125

    126''

    127''

    128''

    129''

    130''

     

    在DC1网络恢复之后,DC1就会从DC2同步126之后的操作,但是会发现这个操作是无法操作的,这时候DC1和DC2就会进入回滚过程,DC1和DC2会查找到二者共同的操作点125,DC1和DC2都会回滚到125,然后二者才会继续后面的同步操作

    注意:如果回滚的数据量比较大需要很长的时间,这时可能会导致回滚失败,对于回滚失败的节点,必须要重新进行同步。一般造成这种情况的主要原因是备份节点远远落后于主节点,而这时主节点挂了。

     

     

     

    备注:

        作者:pursuer.chen

        博客:http://www.cnblogs.com/chenmh

    本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接,否则保留追究责任的权利。

    《欢迎交流讨论》

     

  • 相关阅读:
    类型-String:二进制安全
    影视-纪录片:《魅力柬埔寨》
    植物:探矿植物
    植物-探矿植物:铜草
    扩展名:cs
    扩展名:snk
    Code-Helper:OracleHelper.cs
    Code-Helper:SqlHelper.cs
    Linux: FTP服务原理及vsfptd的安装、配置
    Linux下/etc/fstab文件详解
  • 原文地址:https://www.cnblogs.com/chenmh/p/8608984.html
Copyright © 2011-2022 走看看