当前位置:数据库 > mongodb >>

Mongodb源码分析--Replication之主从模式--Master

mongodb中提供了复制(Replication)机制,通过该机制可以帮助我们很容易实现读写分离方案,并支持灾难恢复(服务器断电)等意外情况下的数据安全。

      在老版本(1.6)中,Mongo提供了两种方式的复制:master-slave及replica pair模式(注:mongodb最新支持的replset复制集方式可看成是pair的升级版,它解决pair只能在两个结点间同步的限制,支持多个结点同步且支持主从宕机时的自动切换, 在1.6版以后提供)。
\

      利用前者,我们可以实现读写分离(主从复制模式),后者则支持当主服务器断电情况下的集群中其它slave自动接管,并升级为主服务器。 并且如果后来的也出错了,那么master状态将会转回给第一个服务器(之前宕机但后来又恢复运行的服务器)。

      同时mongodb支持使用安全认证(enable)。不管哪种replicate方式,只要在master/slave中创建一个能为各个database认识的用户名/密码即可。其认证过程如下:

    slave先在local.system.users里查找一个名为"repl"的用户,找到后用它去认证master。如果"repl"用户没有找到,则使用local.system.users中的第一个用户去认证。local数据库和admin数据库一样,local中的用户可以访问整个db server。


    下面介绍分别介绍一下这两种复制的配置方式:
   
    Master-Slave(主从)模式:
     一个server可以同时为master和slave。一个slave可以有多个master(不推荐,可能会产生不可预期的结果)。

     配置选项:
     --master  以主服务器方式启动
     --slave   以从服务器方式启动
     --autoresync:自动重新sync,因为该操作会copy 主服务器上的所有document,比较耗时,在10分钟内最多只会进行一次。
     --oplogSize:指定master上用于存放更改的数据量,如果不指定,在32位机上最少为50M,在64位机上最少为 1G,最大为磁盘空间的5%。
     --source  主服务器地址(与--slave组合使用)
     --only    仅限于同步指定数据库(下面示例为test库)
     --slavedelay  同步延时

     下面是本人在本地为了测试方便所使用的配置参数
        Master:  IP->10.0.1.103       

mongod --dbpath=d:mongodbdb --master --oplogSize 64
        Slave:   IP->10.0.4.210
       

mongod --dbpath=d:mongodbdb --slave --source 10.0.1.103:27017 --only test --slavedelay 100

    

    补充:受限的master-master复制,这种模式对插入、查询及根据_id进行的删除操作都是安全的。但对同一对象的并发更新无法进行。Mongo 不支持完全的master-master复制,通常情况下不推荐使用master-master模式,但在一些特定的情况下master-master也可用。master-master也只支持最终一致性。配置master-master只需运行mongod时同时加上--master选项和 --slave选项。如下:
     mongod --dbpath=d:mongodbdb --port 27017 --master --slave --source localhost:27018
     mongod --dbpath=d:mongodbdb --port 27018 --master --slave --source localhost:27017

     
    Replica pairs模式
     以这种方式启动后,数据库会自动协商谁是master谁是slave。一旦一个数据库服务器断电,另一个会自动接管,并从那一刻起起为master。万一另一个将来也出错了,那么master状态将会转回给第一个服务器。以这种复制方式启动mongod的命令如下:
     配置选项:
      mongod --pairwith <remoteserver> --arbiter <arbiterserver>
      --pairwith: remoteserver是pair里的另一个server
      --arbiter:  arbiterserver是一个起仲裁作用的Mongo数据库,用来协商pair中哪一个是master。arbiter运行在第三个机器上,利用“平分决胜制”决定在pair中的两台机器不能联系上对方时让哪一个做master,一般是能同arbiter通话的那台机器做master。如果不加--arbiter选项,出现网络问题时两台机器都作为master。
      注:可使用db.$cmd.findOne({ismaster:1})可以检查当前哪一个database是master。

     另外这种模式下的两台机器只能满足最终一致性。当replica pair中的一台机器完全挂掉时,需要用一台新的来代替。如(n1, n2)中的n2挂掉,这时用n3来代替n2。步骤如下:
      1. 告诉n1用n3来代替n2:db.$cmd.findOne({replacepeer:1});
      2. 重启n1让它同n3对话:mongod --pairwith n3 --arbiter <arbiterserver>
      3. 启动n3:mongod --pairwith n1 --arbiter <arbiterserver>。
     在n3的数据没有同步到n1前n3还不能做master,这个过程长短由数据量的多少决定。
 
   
     了解了复制模式之后,还有一个问题需要介绍一下,不是就是本文中mongodb使用cap collection来存储操作日志,并进而使用日志来复制(同步)结点间的数据,其中由主结点保存的操作的记录叫做oplog(operation log的简称)。
 
   Oplog存在一个叫local的特殊数据库中,在oplog.$main集合。Oplog中的每一个文档表示一个在主结点上执行的操作。文档主要包括4块内容,如下:
  

 Ts:操作的时间戳。时间戳类型是一个用来跟踪操作是何时执行的一种内部类型。它由4字节的时间戳和四字节的增量计数器组成。
 Op:执行的操作的类型,大小为1字节。(例如,“i”代表insert,"u":update, "d":delete, "n":none无操作等)
 Ns:执行操作的命名空间(集合名)
 O:执行操作的文档。对于插入,这是将要插入的文档。

     另外这种日志只保存会“改变数据库状态”的操作。查询操作不会记录在oplog中。


     好了,了解这些知识之后,我们就来开始看一下如何调试master-slave模式的源码,首先要在vs2010中打开mongod项目,并将启动参数中设置如下:
      --master --oplogSize 64   (master IP为10.0.1.103)

     如下图:
  
 \

     之后编译该项目,启动该主服务结点,如下:

  \  
     
     接着我们可以在本地或另外一台机器上启动一个slave结点:

  mongod --dbpath=d:mongodbdb --slave --source 10.0.1.103:27017 --only test --slavedelay 100


   下面介绍一下master(主服务端)的代码执行流程。首先我们打开instance.cpp文件,找到下面方法:
  

    //instance.cpp
    // Returns false when request includes end
    void assembleResponse( Message &m, DbResponse &dbresponse, const SockAddr &client ) {
    ......
       if ( op == dbQuery ) {
            if ( handlePossibleShardedMessage( m , &dbresponse ) )
                return;
            receivedQuery(c , dbresponse, m );
        }
        //服务端(master) 收到message执行相关查询操作
        else if ( op == dbGetMore ) {
            if ( ! receivedGetMore(dbresponse, m, currentOp) )
                log = true;
        }
    .....
    }

&

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,