Mongodb中Replication架构

    Mongodb的高可用(HA)架构模式就是replication,replication提供了数据冗余以提高可用性,即将数据在多个servers上备份,当其中部分server失效时,集群仍可以提供服务。在mongodb中,“replica set”(复制集)即为replication模式,复制集为一组mongod实例,它们持有相同的数据集,其中一个实例为primary,用来接收客户端的write请求;其他实例为secondaries,它们从primary同步数据,以保持数据一致性,同时也可以接收客户端的read请求。集群中任何时候只会有一个primary,primary将数据变更操作写入oplog(一个特殊的collection表),那么secondaries从primary中有序的复制oplog中的记录,并在apply到本地的数据集,以此实现“数据同步”,这个机制在很多数据存储系统中都会涉及到;如果primay失效,那么集群将会选举一个secondary成为新的primary。

    上图即为复制集的典型部署图,即一个primary和2个secondary,一个数据将会在整个集群的三个mongod实例中保存,这个拓扑结构也是replication HA中最小的单位。

    我们还可以在复制集中增加一个(或者多个)arbiter实例(仲裁者),arbiter是一个特殊的实例,它本身不保存用户数据,它的主要作用就是和replication中其他成员(members)保持心跳连接,且持有一个投票配额,并在选举时投票。因为arbiter不持有数据,所以它不需要太多的资源开销,如果你的复制集中有偶数(even number)个members,可以考虑添加一个arbiter构成奇数(odd number),这样可以在选举primary时快速达成“多数派”。

    根据上图我们可以看到,通过添加一个arbiter形成一个最小的replica set集群,其中primary和secondary持有实际数据,且负责与客户端交互,而arbiter只是负责在选举时投票,且arbiter不能成为primary(因为它未持有数据),辅助secondary选举为primary,最终让整个集群的部署更加简便。对于很多运维人员而言,构建一个replication需要三个对等的机器配置(内存、磁盘、CPU,因为mongod本身就是资源高耗型),确实比较纠结,arbiter可以“节约”一个secondary,不过事实上它却牺牲了replication的数据担保能力,这种结构,我们认为是旧时代Master-Slaver的替代形式(M-S模式已经被抛弃),不过它额外的提供了更多的特性。(参见下文)

    1、异步复制(Asynchronous Replication)

    Secondaries通过异步的方式从primary上复制数据变更的操作记录,即使复制集中有多个members失效,只要还能形成“多数派”(majority),那么复制操作将不会停止;即只要集群能够正常选举primary、有数据变更记录,那么均可以通过数据复制特性将primary上的数据复制到其他secondaries上。(备注,mongodb中客户端可以通过指定write concern来实现“半同步”、“全同步”等方式)

 

    2、自动failover

    当primary不能与其他的members通信(TCP链接故障)超过10秒(可修改,参看下午rs.reconfig()),那么集群将会尝试将其他的member选举为primary。

 

    3、read操作

    当从primary上读取数据时,可以保证“strict consistency”(严格一致性),默认情况下,客户端总是从primary上读取数据,不过client可以指定“read preference”将读取请求发送到secondaries。“异步复制”意味着secondaries返回的数据不能立即反映出primary的实时数据状态,比如primary上发生的insert(或者update)操作后,oplog还没有同步给secondaries,但是此时发生在secondaries上的read将不能获取相应documents的最新数据状态(直到同步结束)。

 

    在mongodb中,client可以查询到数据可能是尚未持久的:

    1)不考虑“write concern”,当write操作发生后,其他客户端可以在primary上看到write的数据变更,即使操作尚未向客户端确认。即这些write操作仍可能存在“磁盘写入失败”等丢失的风险。

    2)上述中,客户端读取到的数据,有可能此后被“rolled back”。(非事务概念中的回滚,而是primary上write成功,但是没有replicate到secondaries,但是此时primary失效,这就意味着新的primary上丢失了部分数据,旧的primary转换成secondary并加入集群后,需要rolled back那些“超前”的数据并和新primary保持对齐)。

 

    4、其他特性

    复制集还支持一些其他特性,比如“多数据中心”、member权重等等,我们稍后逐个介绍。

 

一、Members(成员)

    复制集中,mongod共有三种成员角色:primary,secondary,arbiter。如上述所述,最小的部署单位可以为“primary + secondary + arbiter”,或者为“primary” + 2个secondaries。一个复制集集群,最多支持50个members,但是最多只能有7个可以投票。

    1、primary(主)

    接收所有的write操作,也可以接收read请求。对于write操作,primary执行成功后,将会写入oplog,那么secondaries通过增量同步oplog并在自己的数据集中apply操作。所有的members(除arbiter)均可以接收read请求,默认情况下,read请求只会发送给primary,我们可以通过设定“read preference”将read请求转发给其他的members。

    2、Secondary(辅助)

    Secondary从primary上复制操作记录(oplog),最终保持与primary一致的数据集合。它的核心要素就是:持有数据的备份;不过secondary可以根据需要设定为“non-voting”(不参与投票选举,rs配置中votes = 0,参看下文)和“primary 0”(权重为0,参与投票,但是不能被选为primary)。复制集集群中至少有一个secondary。Secondaries不能接收write请求,但是可以接收read。当primary失效后,集群通过选举可以将某个secondary选举为primary。

    1)可以通过将secondaries的priority设置为0,以阻止它称为primary;比如希望某个(些)secondary仅作数据备份。“Priority 0”的member不能发起选举,可以投票,和其他普通的secondary一样可以接收read请求。在多个数据中心的应用中,比如有2个数据中心A、B,其中B为容灾备份,那么它的所有的members都应该为“Priority 0”。

    2)可以将secondaries设定为“hidden”,那么它将对用户Client不可见,即不接受用户的read、write请求,也无法被选举为primary,通常“hidden”的member也必须是“priority 0”,但它可以投票。

    3)“Delayed”:一种特殊的member,它保存数据集,不过这个数据集是“落后于”primary一定时间的,比如落后于primary一个小时,那么它将不会包含最近一个小时内的数据;这种member在某些特殊场景下有用,比如“软件升级”、“数据清洗”、“冷备份”,就像snapshot一样,如果在最近一段时间内primary上发生了数据错误,可以通过delayed member来恢复。Delayed member除了具有“delay”选项外,它必须是“hidden”、“priority 0”。

    备注:priority、hidden、votes、slaveDelay等属性可以通过rs配置指定,参见下文。

    3、arbiter(仲裁者)

    它本身不保存数据集,不能被选举为primary;不过arbiter可以投票(vote),当复制集中members的数量为偶数时,我们可以添加一个arbiter构成奇数,因为奇数个members在选举时(election)对达成“多数派”更加容易。尽管arbiter只需要消耗极少的系统资源,但是不要将arbiter与primary、secondaries部署在同一个物理节点上。

 

    在production环境中,复制集通常为三个members,已经基本满足HA需要,因为mongod本身为系统资源高耗型应用,我们应该尽量避免过于复杂的部署方式。如果你需要更多的members参与,则尽可能保证members的个数为奇数,且至少有2个member保存数据;注意replication模式从根本上说并不是解决“负载均衡”、“读写分离”的方法,它是HA方案,即“自动Failover”和数据备份;尽管mongodb的secondaries可以接收read操作,但是对于流量比较高的应用而言,secondaries需要从primary上复制大量的oplog,以及执行和primary等量的write操作,事实上secondaries和primary面对相同的write压力,如果secondaries上再接收较多的read操作,可能导致secondary过载、增加数据复制的延迟。所以当mongod流量较高时,replication模式并不能起到“load balance”或者压力分流的作用,此时应该考虑另一种架构模式:sharding。

    此外,复制集中的所有member都要开启journal(日志)功能,以及设置合适的oplog大小。

 

二、选举

    当复制集初始化(initiating)或者primary失效时,都会触发选举(election),这个过程不需要人工介入。

 

    

    选举过程需要消耗一些时间,在此期间,集群将不能接收write操作(即使旧的primary仍然存活,但因为“网络分区”问题导致它不能与其他secondaries通讯),所有的members(包括旧的primary)都处于只读状态,如果集群中没有“多数派”的members处于有效,那么将无法选举出primary,直到足够的member加入,此时整个复制集处于只读,无法接收write请求。

 

    1)Heartbeats:复制集中的所有members之间都互相建立心跳连接,且每隔两秒发送一次心跳,如果未在10秒内收到回复,则此member将会被标记为“不可用”。

    2)Priority比较:每个member都有权重值,默认为都为1,members倾向于选举权重最高者。上述提到,priority为0的member不能被选举为primary且不能发起选举;只要当前primary的权重最高或者持有最新oplog数据的secondaries没有比它更高的权重时,集群不会触发选举。如果一个拥有更高权重的member加入集群,则会首先catch up当前primary,然后重新发起一轮选举,并将此member选举为primary。

    3)Optime:当前member已经从primary的oplog中应用的最后一个operation的时间戳(此时间戳有primary生成,在oplog中每个操作记录都有);一个member能成为primary的首要条件就是在所有有效的members中它持有最高的optime。

    4)Connections:一个member要成为primary,它必须与“多数派”的其他members建立连接,如果未能与足够多的member建立连接,事实上它本身也无法被选举为primary;不过对于谁将成为priamry而言,多数派参考的是“总票数”,而不是member的个数,因为我们可以给每个member设定不同的“票数”。比如有三个member,每个member持有一票(vote),那么只要至少有2个member可以互相通信(3的多数派至少为2),即可选举;不过如果有2个member不可用,将无法选举,剩余的那个member如果是primary,那么它也将step down并成为secondary,整个复制集处于只读状态。

    5)网络分区(Network Partitions):即集群中一部分members无法与其他members通讯,而分割成多个区域;因为选举是基于“多数派”(一个member需要与多数派建立连接,且票数也是多数派),所以网络分区时,无法进行选举(未能形成多数派时)。为了避免这种问题,建议将集群中的多个members分别部署在多个物理网段中。

 

    选举触发时机:1)复制集初始化时,此时没有primary 2)一个secondary与primary失去连接,此时它将发起选举;如果多数派的secondaries均与primary失去连接,则选举即可进行成功,否则选举将会被正常的members否则(veto)。 3)primary关闭(step down)。

    需要注意,“Priority 0”将无法发起选举,即使它与primary失去连接,它只能对别人的选举进行“投票”或者“否决”。

    我们可以通过rs.stepDown()方法或者replSetStepDown命令来关闭primary,或者当有更高优先级的secondary加入时,或者当前primary无法与大多数members建立连接时,primary也会关闭,此后将触发新一轮的选举。此外,我们通过rs.reconfig()修改了复制集的配置后,也有可能会触发选举。当primary关闭时,它会关闭所有的客户端连接,此后客户端将无法write。

 

    选举规则:

    每个member都有一个priority属性,用来表示它们成为primary的资格,集群将会选举priority最高的member成为primary,默认情况下,所有的member的权重均为1,即它们有相同的机会成为primary。如果你倾向于某个member成为primary,可以将其priority的值设置的更高。默认情况下,每个member持有一个vote(票数),如果大多数member都选举某个member,那么它将成为primary;“Non-voting” member的vote值为0,且目前所有的member的vote值不能大于1。(即每个member只能投一票,或者不投票)

 

    选举中否决:

    所有的member都可以否决选举,包括“Non-voting”。将会在如下情况时否决选举(否决提议者):

    1)如果提议选举的member不属于当前复制集(配置文件中未声明) 2)提议选举的member数据陈旧  3)提议选举的member priority比已知的其他member低 4)如果当前primary比提议选举者持有更高的optime 

    如果权重最高的member没有持有最高的optime,那么它将首先跟进optime最高的secondary,然后才能成为primary。

 

    Rolled back:

    前文已经提到“rolled back”:priamry失效之前,未能把write操作复制给大多数secondaires,此后选举出了新的primary,那么新的priamry也接受了部分write请求,那么当旧的priamry再次加入集群,它上面的数据有一些与当前priamry是“不对齐”的,那么旧的priamry则需要将那些“未对齐的”数据进行回滚,并与新的priamry保持数据一致。通常情况下,我们应该避免“rolled back”,因为这是一种比较危险的“数据不一致”的情况。rolled back数据被保存在“dbPath”路径下rollback目录中。

    默认情况下,客户端的write concern为{w : 1}即write操作在primary上写入成功后就会向客户端返回结果,这种情况下,如果primary失效且数据尚未复制到secondaries时,会发生rolled back。为了避免rollback,客户端可以使用{w : majority},当write操作在大多数secondaries上写入成功后才会向客户端返回结果。

 

三、读写机制

    1、write concern

    默认情况下,write concern为只会在primary上提交write操作,我们可以重写这种设置将write操作提交到指定个数的secondaires上:

    write concern提供了mongodb在replication模式中的数据写入保证机制,write concern强度决定了保障级别,当insert、update、delete操作持有较弱的write concern,那么write操作将会立即返回,不过在当发生异常时,较弱的concern将无法保证写入操作被持久化;较强的concern,意味着write操作需要在更多的secondaries上执行(有图可见,依次在secondaries上提交write),客户端需要更多的等待时间。mongod提供了多种级别的write concern,它们有几个重要的选项:

    1)w

    表示write操作在多少个members上提交成功才会向客户端返回确认信息,默认为1。值为1表示当write操作在primary上执行成功后会即返回确认信息(Ack),0表示客户端发送write操作后不需要等待任何确认信息,有点异步操作的意味,这也意味着客户端无法知道此次write请求是否在server端执行成功,当然这个级别也是write操作吞吐能力最强的;"majority"表示write操作在大多数members上执行成功后才向客户端返回确认信息;我们可以指定一个合适的<number>,表示write操作需要在指定数量的member上执行成功才会返回确认信息,此期间客户端一直等待;此外每个member还可以指定一个tag(标签),w的值可以为tag的名字,表示write操作需要在指定tag名称的members上执行成功。通常情况下,“majority”是个不错的选择,可以有效避免rolled back;如果你希望更高的插入效率,可以设置为0。(猜测:当primary将write操作发送给secondary之前,有可能触发将此write操作之前的尚未同步的oplog首先发送过去,否则会导致一些混乱)

    2)j

    即journal,值可以为true或者false,表示客户端是否需要等待write操作被写入journal日志的磁盘文件(flush到磁盘),写入journal日志可以保证当mongod异常退出后数据不会丢失,可以在启动时自动恢复。只需要primary节点上的jounral日志写入磁盘即可,即只对primary有效。(需要复制集中所有的member都开启journal功能,因为它们都有可能成为priamry;当j : true时要求每个write操作都会强制journal日志写入磁盘,对并发能力有一定的影响,这是一个值得权衡的参数)

    3)wtimeout

    指定write操作超时时间,即primary需要等待确认信息的最长时间,单位毫秒。因为write操作通过指定“w”和“j”参数后,会增加write操作的等待时间,当priamry等待其他memeber反馈信息超时后,将会向客户端返回error信息;可能操作在某些节点上已经执行成功,但mongod不会undo此操作。很遗憾,这种机制会导致一定的数据不一致性,比如客户端收到error信息,但是事实上write操作已经在某些member上执行成功了。如果不指定wtimeout值或者为0,那么客户端(包括primary)一直等待,直到满足条件(足够多的member执行成功)。

db.products.insert(
   { item: "envelopes", qty : 100, type: "Clasp" },
   { writeConcern: { w: 2, wtimeout: 5000 } }
)

     

    2、read preference

    “read preference”用来描述mongodb client如何路由read请求。默认情况下,read请求发送给primary,不过如果系统的read请求量很大,primary可能无法承载,此时需要将部分请求分散在其他secondaries上,不过从secondaries上read数据,有可能读取不到最新的数据,因为primary到secondaries的数据同步,是有延迟的。

    1)primary : 默认模式,所有的read操作均在primary上。

    2)primaryPreferred:read操作在primary上,如果primary失效,则从secondaries上读取数据。

    3)secondary:read操作在secondary上。

    4)secondaryPreferred:read操作在secondary上,如果所有的secondary失效,则从priamry上。

    5)nearest:客户端会间歇性的评估它与所有members之间的网络延迟,read操作发给延迟最小的member。

 

    对于复制集,所有的member都承担相等的write压力,因为最终每个write操作都会在所有的member上执行,如果secondary上有较高的read压力,会增加它与priamry数据同步的时间延迟,且从secondary上读取数据还有不一致的风险;如果你的应用需要数据正确性,建议使用primary模式或者primaryPreferred,否则可以考虑使用“secondary”等。

 

    前文中提到oplog,即operation log,oplog并不是保存在普通的文件中,它是一个特殊的capped collection,用于保存所有的数据变更操作,primary将write操作执行成功,并写入oplog,此后secondaries复制并在本地应用;复制集中所有的member都有一份oplog备份,oplog保存在“local.oplog.rs”这个collection中(其中local为db名)。所有member之间都互相建立了链接,因此任何一个member均可以从其他memeber复制oplog。对于oplog中记录,在member上应用一次和应用多次,所得到的结果是一样的,即oplog中的操作是幂等的,这有点像数据库binlog的“row”模式。

    当复制集中的member首次启动时,会根据默认size创建oplog,具体的size依赖于部署的操作系统配置(比如64位linux,为磁盘的5%),我们可以修改oplog的size以适合自己的应用。通常我们尽可能的保证复制集中所有的member的oplog尺寸都一样,此外,如果你的应用write量较大,可以设置较大的size,否则可以设置较小的size。(修改尺寸的方式,就是删除当前的oplog,然后在新建时指定size)

db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } )

    不过在绝大多数情况下,默认的oplog尺寸基本可以满足,不过如果有如下情形,可以考虑增加size:

    1)update多个document:一次update操作,更新多条(通常是数量很大)文档时;因为oplog为了保证幂等性,需要将更新的每条document最终数据状态都写入oplog,这可能导致oplog产生大量的数据。

    2)delete:批量delete,基本情况同1),虽然不会导致db的数据尺寸增加,但是仍会产生大量oplog。

   我们可以通过“rs.printReplicationInfo()”方法查看oplog的使用情况。

 

    3、readConcern(3.2+版本)

    mongodb 3.2+版本提供了readConcern特性,对wiredTiger引擎有效,readConcern允许客户端选择read操作的隔离级别(类似与writeConcern);可以指定此选项值为“majority”表示只读取那些已经在majority个members上写入成功的数据,以避免“rollback”的发生;也可以指定为“local”表示只要本地数据可见就能read(write操作在本地内存或者数据文件成功的,但不保证已经在replica set多个节点同步成功),不过这可能出现“rollback”(即primary失效,可能导致有些尚未同步的数据丢失,类似于“不可重复的读”)。默认此值为“local”。如果想开启“majority”需要在配置文件中新增如下配置:

replication:
    enableMajorityReadConcern: true

 

collection.withReadConcern(ReadConcern.MAJORITY).find().iterator();

 

四、部署

    本人在单机上尝试部署3个mongod,构建一个简单的replica set集群,其中一个为priamry,两个secondaries。

#mongodb 0
port 27017
dbpath /data/mongo_0/db

#mongo 1
port 28017
dbpath /data/mongo_1/db

#mongo 2
port 29017
dbpath /data/mongo_2/db

 

    1、完整配置:

systemLog:
    quiet: false
    path: /data/mongodb_0/logs/mongod.log
    logAppend: false
    destination: file
processManagement:
    fork: true
    pidFilePath: /data/mongodb_0/mongod.pid
net:
    bindIp: 127.0.0.1
    port: 27017
    maxIncomingConnections: 65536
    wireObjectCheck: true
    ipv6: false	
storage:
    dbPath: /data/mongodb_0/db
    indexBuildRetry: true
    journal:
        enabled: true
    directoryPerDB: false
    engine: mmapv1
    syncPeriodSecs: 60 
    mmapv1:
        quota:
            enforced: false
            maxFilesPerDB: 8
        smallFiles: true	
        journal:
            commitIntervalMs: 100
    wiredTiger:
        engineConfig:
            cacheSizeGB: 8
            journalCompressor: snappy
            directoryForIndexes: false	
        collectionConfig:
            blockCompressor: snappy
        indexConfig:
            prefixCompression: true
operationProfiling:
    slowOpThresholdMs: 100
    mode: off
replication:
    oplogSizeMB: 1024
    replSetName: rs_sample

    上述为mongo_0的配置,对于其他两个mongod需要修改配置中的路径,因为我们仅仅是测试用,所以oplogSizeMB参数就设置的小了一些,在production环境中需要调整的更大(比如10240),最重要的配置就是“replication”部分,它们必须有相同的“replSetName”值。创建三个配置文件“mongo_0.conf”、“mongo_1.conf”、“mongo_2.conf”放在mongodb的安装路径下。需要注意,在每个dbpath目录下,还要手动创建“db”、“logs”两个子目录,否则可能导致启动失败。

    2、启动

#启动mongo 0
./mongod -f mongo_0.conf

#启动mongo 1
./mongod -f mongo_1.conf

#启动mongo 2
./mongod -f mongo_2.conf

 

    3、复制集初始化

#使用mongo shell连接到任意一个mongod实例,比如“mongo 0”
#mongo 0 shell
> ./mongo --host 127.0.0.1 --port 27017 
> rs.initiate()

    rs.initiate()指令就是初始化复制集,比如创建oplog、生成复制集的一些配置信息等。然后我们通过rs.conf()指令可以查看到,此时“mongo 0”(即当前mongod)默认已经成了复制集的member;members是一个JSON数组,会列举出当前复制集中所有的member以及其属性,此时我们只看到一个member,而且host信息似乎有些不太“美观”,我们可以通过如下方式修改host值,当然member的所有属性都可以通过这种方式修改:

#mongo 0 shell
> cfg = rs.conf();
> cfg.member[0].host = "127.0.0.1:271071";
> rs.reconfig(cfg);

    修改host时,需要注意保证复制集中其他的member能够访问,且和配置文件中绑定的地址一样(或者解析后的地址一样)。

 

    4、新增member

#mongo 0 shell
> rs.add("127.0.0.1:28017");
> rs.add("127.0.0.1:29017")

    新增2个member,rs.add(String host, boolean arbiter)允许接受个参数,第一个为host,格式可以为address:port,address可以为ip地址或者域名,第二个参数为可选,表示此member是否为arbiter,默认此值为false。注意,无论何时,host名称必须与相应的member配置文件中的bind_ip参数保持一致。

 

   此后我们可以通过rs.conf()查看当前配置,示例如下:

#mongo 0 shell
rs_sample:PRIMARY> rs.conf();
{
	"_id" : "rs_sample",
	"version" : 4,
	"members" : [
		{
			"_id" : 0,
			"host" : "127.0.0.1:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "127.0.0.1:28017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "127.0.0.1:29017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatTimeoutSecs" : 10,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		}
	}
}

    rs.add()方法执行成功后,当前mongod将会与指定的host建立连接,并开始选举primary;并且我们操作的config信息也将同步给其他members,尽管我们没有在“mongo 1”、“mongo 2”上执行任何操作,我们通过shell连接到“mongo 1”或者“mongo 2”,通过rs.conf()仍然可以查看到复制集的配置信息;因为对于修改复制集的配置而言,我们只需要在一个member上(通常为primary)操作即可,同时rs.initiate()方法也只需要在第一个member上执行一次即可。

 

    5、其他复制集指令

    1)rs.help() :输出所有的复制集有关的操作方法列表,这是一个帮助方法。

    2)db.shutdownServer() :优雅关闭当前server,通常情况下我们不建议使用kill进程的方式关闭,此指令可以让mongod安全退出,不会导致数据异常。

    3)rs.addArb(String host):添加一个arbiter。

    4)rs.conf():输出当前复制集的配置信息。我们从上文中可见,配置信息中包含了所有的可调节参数,比如“heartbeatTimeoutSecs”、priority、w(write concern默认值)等等。

    5)rs.freeze(int seconds):通常在维护时使用,如果当前mongod需要维护,比如升级、数据清洗等,freeze方法将导致当前member在指定时间内不能成为primary,即取消参选资格,但可以投票。

    6)rs.initiate(Document config):初始化复制集配置信息,config参数为可选,如果没有指定config,则默认将当前mongod实例作为首个member加入配置,否则将使用指定的config。

    7)rs.printSlaveReplicationInfo():输出secondaries的状态,主要是可以查看它们数据同步的情况,结果样例如下:

rs_sample:PRIMARY> rs.printSlaveReplicationInfo();
source: 127.0.0.1:28017
	syncedTo: Tue Nov 03 2015 21:25:25 GMT+0800 (CST)
	0 secs (0 hrs) behind the primary 
source: 127.0.0.1:29017
	syncedTo: Tue Nov 03 2015 21:25:25 GMT+0800 (CST)
	0 secs (0 hrs) behind the primary 

    8)rs.reconfig(Document config,boolean force) :重新配置复制集,旧的配置信息将会被覆盖。此方法需要在primary上执行;其中force为可选参数。此方法在某些情况下将会导致primary被step down,比如修改了primary的priority,或者增减了members等;当primary关闭后,其上客户端连接也会被强制关闭,并开始选举。

cfg = rs.conf();
cfg.members[1].priority = 2;
rs.reconfig(cfg);

 

    9)rs.remove(String hostname):从当前复制集中移除指定host的member,host的值必须与conf信息中的host完全一致;在移除member之前,首先需要将此member关闭。

    10)rs.status():可以查看集群中每个member的状态,比如是primary还是seconday,optime,健康状况等。

    11)rs.stepDown():需要在primary上执行此方法,表示关闭当前primary,并由此出发新的选举。

 

    6、修改属性

    在上文中我们通过rs.conf()能够查看复制集的配置信息,展示出所有的memebers以及【setting信息】,我们可以像修改host那样修改其他属性,比如priority、hidden类型、votes值等。

##将member[0]修改为delayed member
cfg = rs.conf();
cfg.members[0].hidden = true;
cfg.members[0].votes = 0;
cfg.members[0].slaveDelay = 3600
##修改复制集的setting信息
cfg.setting.getLastErrorDefaults.w = "majority";
cfg.setting.getLastErrorDefaults.wtimeout = 12000

rs.reconfig(cfg);

 

五、JAVA编码示例

    1、pom.xml

      <dependency>
          <groupId>org.mongodb</groupId>
          <artifactId>mongodb-driver</artifactId>
          <version>3.1.0</version>
      </dependency>
   2、java示例

 

List<ServerAddress> replicaSet = new ArrayList<ServerAddress>();
replicaSet.add(new ServerAddress("127.0.0.1",27017));
replicaSet.add(new ServerAddress("127.0.0.1",28017));
replicaSet.add(new ServerAddress("127.0.0.1",29017));
MongoClientOptions options = MongoClientOptions.builder().writeConcern(WriteConcern.MAJORITY)
        .connectTimeout(30000)
        .connectionsPerHost(128)
        .heartbeatConnectTimeout(15000)
        .heartbeatFrequency(10000)
        .maxConnectionIdleTime(60000)
        .maxWaitTime(10000).build();
MongoClient mongoClient1 = new MongoClient(replicaSet,options);
MongoDatabase db = mongoClient.getDatabase("test");//获取DB

 

    或者使用MongoClientUri来构建:

MongoClientURI connectionString = new MongoClientURI("mongodb://127.0.0.1:27017,127.0.0.1:28017,127.0.0.1:29017");
MongoClient mongoClient = new MongoClient(connectionString);

    mongodb客户端提供了server自动发现功能,即间歇性的与每个server发送心跳以判断server是否可用,如果发现不可用,客户端将尝试与其他server建立连接,客户端也能区分出members的角色:primary还是secondary;开发者在构建MongoClient时,只能指定能够进行读写操作的host列表,如果需要调优,可以配置合适的连接池相关的options。

 

单台windows搭建mongoDb主从集群 NULL 博文链接:https://ljlowkey.iteye.com/blog/2113520 立即下载

相关推荐

从零到一:用CubeMX和485模块快速上手多摩川绝对式编码器(附清零操作详解)

本文详细介绍了如何使用STM32CubeMX和485模块快速上手多摩川绝对式编码器,包括硬件连接、STM32配置、协议解析及清零操作。通过具体的代码示例和调试技巧,帮助开发者高效实现编码器数据读取和清零功能,特别适合STM32单片机开发者参考。

weixin_30599769的博客 192

mongodb 基本原理:副本(Replication)

mongodb 的副本集(replica set) ,是一组维护相同数据的进程集合,为数据提供冗余和高可用。(high availability) 数据冗余和数据可用 副本提供了冗余和可用性。在不同的db服务器上维护数据的多份副本,针对单db服务的宕机提供了容错性。同时还可以增加读性能,因为读请求可以分散到不同的服务器中。(容灾、备份、高可用) mongodb 的副本 一个副...

guangyacyb的博客 1042

大白话讲解Numpy中什么是一维、二维、三维数组,以及5种创建方式

NumPy中提供了多种创建数组的方式,其中最基本的方式就是通过array()函数创建数组在使用该函数时直接传入列表或元组即可。 通过array()函数分别创建一维数组、二维组和三维数组,那么什么是维度呢?一维、二维、三维有什么区别? 1、什么是维度? 维度可以理解为描述数据的一种 “方向” 或者 “层次”。在数组中,维度的数量决定了我们需要用多少个索引来访问一个元素 2、一维、二维、三维的区别? (1)一维:一维数组就像是一条直线上排列的一组数据,例如: a = np.array([1, 2

1362

MongoDB replication

MongoDB的副本集能保证数据库服务的冗余性和高可用,这也是生产环境的必要配置。每个副本集都保存相同的数据,保证主节点异常时能接替主节点继续提供服务。

Blue summer的博客 1531

SuccessFactors入门篇

SuccessFactors入门篇—— Employee Central(一)最近通过一个月左右的学习,拿到了SF EC(SuccessFactors Employee Central )模块SAP认证,所以打算把自己学习SF的整个过程以及相关资料和大家分享一下,相互切磋,共同进步。Employee Central简单了解Employee Central简单了解新的改变功能快捷键合理的创建标题,有...

qq_42288853的博客 1万+

保姆级教程:用LoRA微调Chinese-Mistral-7B模型,并一键部署到Ollama(附完整代码)

本文提供了一份详细的LoRA微调Chinese-Mistral-7B模型的保姆级教程,涵盖环境配置、数据预处理、微调实战、模型量化及Ollama部署全流程。通过实战案例和完整代码,帮助开发者快速构建专属中文大模型,适用于医疗、法律等垂直领域。

weixin_30369041的博客 249

MongoDB的Replication简单介绍

 MongoDB的Replication简单介绍 1. 什么是Replication数据复制是为了使数据得到最大的可用性,避免单点故障的发生,MongoDB支持在服务器之间进行数据的异步复制,来满足数据的最终一致性。但是同一时刻只有一台服务器是可以写的。当只有一台master时,数据的强一致性就可以得到保障。但当用户从slaves上去读数据时,这里只能保障数据的最终一致性。目前MongoDB提供了三种Replication方式,Matser/Matser, Matser/Slave,Replica Sets

lemo的专栏 6904

从多项式到神经网络:DPD算法演进史及其在RRU中的工程实现

本文系统梳理了数字预失真(DPD)算法从经典多项式模型、查表法到神经网络驱动的演进历程,并深入探讨了其在基站射频单元(RRU)中面临的硬件资源约束与工程实现挑战。文章为通信设备的技术决策者提供了算法选型、性能权衡及混合架构设计的实用评估框架,助力在性能、功耗与成本间找到最优平衡。

cherry的博客 1076

MongoDB 官方文档笔记之复制 Replication

主节点会将所有写操作记录到日志中,即 oplog,从节点复制主节点的 oplog,并将这些操作应用在从节点上。主节点挂掉之后,从节点会通过选举产生新的主节点。如果主节点与集群中其他节点通信超时,超过 electionTimeoutMillis 配置的时间,从节点会发生选举。在初始化复制完成之后,从节点会再同步源复制 oplog,异步的应用这些操作。也支持多线程并发复制。建议最少配置一主两从三成员副本集,但假如只有一主一从两个节点,则可以加入一个。主节点上的更新日志 oplog,会异步同步给从节点。

菜皮日记 271

北斗导航 | 卡尔曼滤波与因子图优化对比(附图优化matlab代码)

- 历史数据利用:因子图通过滑动窗口保留历史状态,优化时联合多帧数据;卡尔曼滤波仅依赖当前和上一帧状态 。 - 迭代优化:因子图通过多次迭代逼近最优解,卡尔曼滤波仅单次更新 。 - 误差抑制:因子图的多次线性化可有效抑制非线性误差(如GNSS伪距观测的非线性) 。

尘世冰封的专栏 1303

C#实现每日定时执行制定程序(附完整源码)

C#实现每日定时执行制定程序(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 866

MongoDB中副本集-Replication

之前的博文 MongoDB主从复制架构中 ,讲述了MongoDB用来实现数据冗余的一种方式,也提到了主从复制的缺点,当主节点出现故障时,数据库服务不可用,因此很多数据库也都选择了新的方式替代主从复制 , 比如MongoDB的复制集、redis的哨兵机制等,本文就是描述 MongoDB的复制集的相关特性。 1. MongoDB中副本集的特点 副本集(或者叫复制集,名字无所谓)是MongoDB用来实...

leedh_码农 579

IPD流程中的RR\OR\IR\PB\SR\AR\CR等名词汇总(基于新的产品包需求架构)

RR:Raw Requirement,原始需求=》IR:Initial Requirement,初始需求=》SR:System Requirement,系统需求=》AR:Allocated Requirement,分配需求=》CR:Process Change Requirement,流程变更需求。

a1809032425的博客 3189

mongodb之高可用架构

mongoDB 高可用mongoDB支持在多个机器中通过异步复制达到故障转移和实现冗余。多机器中同一时刻只有一台是用于写操作。正是由于这个情况,为mongoDB提供了数据一致性的保障。担当主角色的机器能把读操作分发给slaves/secondaries。mongodb 高可用可用分两种* Master-Slave Replication* Replica Sets以下为两个的架构图: ...

weixin_30263073的博客 194

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

mongoDB3.4的sharding集群搭建及JavaAPI的简易使用

第一部分 在搭建mongoDB之前,我们要考虑几个小问题: 1、我们搭建集群的目的是什么?是多备份提高容错和系统可用性还是横向拓展存储大规模数据还是两者兼有?   如果是为了多备份那么选择replication集群搭建即可,如果是为了处理大数据则需要搭建sharding集群,如果两者兼有需要对每个shardsvr创建replica。 2、什么是sharding?和replication有什...

weixin_30487701的博客 183

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

MongoDB AutoSharding+Replication sets稳定性测试

MongoDB AutoSharding+Replication sets稳定性测试 单Replication sets设计: 如图所示,10.9.3.228只启动Mongos和config两个服务 view plainprint? ^_^[root@:/usr/local/mongodb/bin]#cat runServerConfig.sh   ./mongod --con

340

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

复制集群架构设计技巧

复制集群架构设计技巧

lee_nacl的博客 634

常用数据库高可用和分区解决方案(1) — MySQL篇

在本文中我们将会讨论MySQL、Oracle、MongoDB、Redis以及Oceanbase数据库,大家可能会奇怪为什么看不到有名关系型数据库MSSQL、DB2或者有名NoSQL数据库Hbase、LevelDB等,最主要原因是我对这些数据库熟悉层度不够。但相信这些数据库都会有相应的解决方案。   首先我们看一下数据库以及常看到的HA以及分布式架构方案  

mengtianyalll的专栏 1574

Replication

分布式系统设计的时候需要考虑Failure Recovery和Replication,从而支持线上实时服务。Replication可简单分为单点的replication及整个系统(数据中心)的replication。为了简单起见,GFS/Mapreduce/Bigtable等分布式系统都采用单Master设计,国内很多互联网公司甚至把写数据节点设计成单点以避开一致性及负载平衡问题,因此Replic

388

MongoDB 分片迁移

目前集群架构 mongos + config server * 3 + shard * 2 ( replication * 3) 首先使用mongo终端连接到mongos. 检查 balancer 是否开启 (必须为开启) mongos> sh.getBalancerState() true 确定要删除的分片的名字,查看分片状态 mongos> db.printShardingStatus() --- Sharding Status --- sharding version

Light_Dream的博客 2714

Mongodb集群部署以及集群维护命令

MongoDB集群帮助手册 一、Mongodb集群架构简介 这是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建monodb系统。  要构建一个 MongoDB Sharding Cluster,需要三种角色: l  Shard Server: mongod 实例,用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组...

lipeng的博客 402

Mongodb高可用架构

Mongodb高可用架构 健壮方案 1.    多个配置服务器 2.    多个mongos服务器 3.    每个片都是副本集 4.    正确配置w   阻塞复制 开发者可以用gerLastError的"w"参数来确保数据的同步性.这里运行gerLastError会进入阻塞状态,知道n个 服务器复制了嘴型的写入操作为止 db.runCommand({"gerLastErro

ctf_htj的专栏 1388

MongoDB 2015回顾:全新里程碑式的WiredTiger存储引擎

编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由毕洪宇分享。转载请注明来自高可用架构公众号「ArchNotes」。毕洪宇,唯品会实时计算平台资深开发工程师...

weixin_45583158的博客 252

MongoDB 副本集replSet 配置与分析

2个Standard节点+1个Arbiter节点 搭建MongoDB Replication Sets 创建目录 [root@localhost ~]# mkdir -p /data/replset/r0 [root@localhost ~]# mkdir -p /data/replset/r1 [root@localhost ~]# mkdir -p /data/replset/

irelandken的专栏 1万+
上一篇: Mongodb中Index特性
下一篇: Mongodb存储特性与内部原理
iteye_19607
博客等级 码龄8年 34粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值