MongoDB副本集(二)

二、复制过程

    副本集成员不断复制数据。首先,一个成员使用初始的复制来捕捉数据集,然后持续地记录和应用每一个数据集上的操作。每一个成员记录自己的Oplog。
    · 副本集Oplog
    · 副本集数据复制

1、副本集Oplog

    Oplog(operation log)是一个特殊的封装集合,是对存储在数据库中的数据的所有修改操作进行一个滚动的记录。MongoDB应用数据库操作到primary,并将操作信息记录到primary的Oplog中。secondary成员然后通过复制进程,复制和应用这些操作。所有的包含Oplog副本的副本集成员,被记录在local.Oplog.rs集合中,来允许他们维护数据库的当前状态。
    为了方便复制,所有的副本集成员发送心跳(pings)到其他所有的成员,任何成员可以导入其他成员的Oplog。
    无论是否应用一次或者多次到目标数据集,Oplog中的每一次操作产生相同的结果,也就是,Oplog中的每一个操作都是等幂的。合适的副本集操作,Oplog中的条目一定是等幂的:
    · 最初的sync
    · 随后的rollback和追赶
    · 分片块迁移

a.Oplog的大小

    当你第一次使用副本集的成员时,MongoDB创建一个默认大小的Oplog,大小取决于操作系统。
    在多数情况下,默认的Oplog大小是充足的。例如,如果一个Oplog占用空闲磁盘5%的空间,并会在24小时的操作中填满,这时secondary会停止复制Oplog多达24小时,而不至于让持续地复制导致未应用的Oplog变得陈旧。然而,大多数副本集设置拥有更低的操作容量,他们的Oplogs可以承受更多的操作数量。
    在MongoD创建Oplog前,你可以通过OplogSizeMB选项指定大小。然而,在你第一次启动了一个副本集成员后,你只能通过change the size of the Oplog过程来修改Oplog的大小。
    默认的Oplog的大小如下:
    · 对于64位的linux、solaris、freeBsd和windows系统,MongoDB分配5%的空闲磁盘空间,但是经常会分配至少1G,最多不超过50G的空间。
    · 对于64位的OS X系统,MongoDB分配183M的空间给Oplog
    · 对于32位的系统,MongoDB分配大约48M的空间给Oplog
    工作负荷可能会要求需要更大的Oplog
    如果你可以预测你的副本集的工作负荷,类似于以下模型,这时你可能想创建一个比默认大小更大的Oplog。相反,如果你的应用是read主导和少许的写操作,一个更小的Oplog可能更加合适。以下的工作负荷可能需要更大的Oplog:
    · 一次性更新多个文档:Oplog必须将多更新转换为单更新操作来保证等幂。这就会用到大量的Oplog空间而不是相应的数据大小增长或磁盘占用。
    · 删除和插入同样数量的数据:如果你粗略地删除你插入的数据,数据库不会再磁盘使用上不会明显地增长,但是Oplog会变得相当大。
    · 大数量的原位置更新:如果工作流的原位更新并没有增长文档的大小,数据库记录了大量的操作,但是并不会修改磁盘上的文档数量。

b.Oplog状态

    想查询Oplog的状态,包括大小和操作的时间分布,使用rs.printReplicationInfo()方法。
    在各种异常的情况下,更新到一个secondary的Oplog可能会延迟于预期的时间。在secondary成员上使用db.getReplicationInfo(),会输出副本集状态来评估副本集的当前状态并确定是否有任何非故意的复制延迟。

2.副本集数据复制

    为了维护最新的共享数据集的副本,副本集的成员从其他成员处复制或复制数据。MongoDB使用2种数据复制的表格:初始复制来完全填充新成员的数据集,复制来应用不断变化到全部的数据集。

a.初始化复制

    初始化复制,将副本集中一个成员的所有数据复制到另一个成员。一个成员在没有任何数据的时候(例如,新加入的成员,或者已经删除、遗失了历史数据的成员),会采用初始化复制。  
    当采用初始化复制时,MongoDB将执行:
    · 复制所有的数据库。先查询来源的每一个数据库的所有集合,然后将所有数据插入到自身的数据库集合中。此时,会建立_id索引。克隆进程仅仅复制可用数据,忽略不可用文档。
    · 应用所有的Oplog更改到副本集。从来源处获取Oplog,然后应用这些Oplog,从而更新自身数据来反射副本集的最新状态。
    · 在集合上建立索引。
    当MongoD完成以上工作时,此成员可以可以转变为正常状态。

b.复制

    成员在初始化复制后,会持续地复制数据。这个过程保证了成员可以将数据更新到最新。多数情况下,secondary从primary处复制。基于ping和其他成员的状态,必要时secondary会自动的修改他们的复制源。
    当一个成员从另一个成员进行复制时,两者在索引设置上必须一致。
    注:从version2.2开始,secondary将避免从延迟成员、隐藏成员出复制数据。
    有效性和持久性:在一个副本集中,最多有一个primary,并且只有primary可以接收write操作。secondary从primary处异步地应用操作来提供最终的一致性。日志提供了单实例的write持久性。没有日志,若MongoDb实例不幸终止,数据库将处于不可用状态。在MongoDb中,客户端可以在数据变得持久性前查看write结果(尽管随后可能会被rollback)
    多线程复制:MongoDb通过多线程来提供了批量写操作,提高并发量(每一次批量写操作,称为一个批次)。MongoDb通过namespace或者文档id来对批次分组,同时使用不同的线程应用这些不同的批次。MongoDb经常对于一个文档按照write顺序来应用这些write操作。应用一个批次时,MongoDb会锁定所有的write操作。因此,secondary的read查询永远不会返回不存在于primary中的数据。
    预读取索引来提升复制能力:使用MMAPv1存储引擎,MongoDb加载被影响数据和索引到内存中,来提升应用Oplog的性能。预读取,最小化了MongoDb应用Oplog时,持有write锁的时间。默认情况下,secondary会预读取所有的索引。选择性地,你可以关闭预读取,或仅仅预读取_id索引字段,通过secondaryIndexPrefetch设置来查看更多的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值