一、复制原理

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

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

《欢迎交流讨论》

MongoDB入门系列:复制机制的更多相关文章

  1. MongoDB入门系列(一):基础概念和安装

    概述 MongoDB是目前非常流行的一种非关系型数据库,作为入门系列的第一篇本篇文章主要介绍Mongdb的基础概念知识包括命名规则.数据类型.功能以及安装等. 环境: OS:Windows Versi ...

  2. MongoDB入门系列(二):Insert、Update、Delete、Drop

    概述 本章节介绍Insert.Update.Delete.Drop操作基本语法. 环境: Version:3.4 insert insert()基本语法如下: db.collection.insert ...

  3. MongoDB入门系列(三):查询(SELECT)

    一.概述 mongodb是最接近关系型数据库的NOSQL数据库,它的存储方式非常的灵活:以至于你会将它看成是一个经过冗余过的关系型数据库的表,这也是Mongodb原子性的一个特征.由于没有关系型数据库 ...

  4. MongoDB入门系列(四):权限管理

    一.概述 本篇文章主要介绍如何创建用户和角色相关概念,同时对角色的添加和删除做了相关介绍. 版本:3.6.2 二.角色相关概念 1.数据库用户角色 read:该角色拥有数据的只读权限,系统集合以及sy ...

  5. MongoDB入门系列之科普篇

    ​ 目录 背景 对比 MongoDB的数据存储格式 背景 最近公司扩展了很多国外客户,那么一个很严重的问题就是翻译,对于国外客户来说,肯定看不懂中文,那就要项目中提供切换各自国家语言的功能. 由于每个 ...

  6. Redis系列(四):Redis的复制机制(主从复制)

    本篇博客是Redis系列的第4篇,主要讲解下Redis的主从复制机制. 本系列的前3篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装 Redis系列(二):Redis的5种数据 ...

  7. 【Ecmall】ECMall2.x模板制作入门系列(认识ECMall模板)

    ECMall2.x模板制作入门系列之1(认识ECMall模板) 从ECMall2.0全新架构发布以来,随着版本的不断更新,ECMall已经逐渐走向一个稳定时期,是时候整理一些实用教程了.下面给大家带来 ...

  8. ECMall2.x模板制作入门系列之2(模板标签/语法)

    ECMall2.x模板制作入门系列之2(模板标签/语法) 今天给大家带来一个模板语法的教程.希望能为ECMall模板制作者提供一份参考资料.如有问题.建议和意见,欢迎提出. 在ECMall模板中,用& ...

  9. MongoDB 事务,复制和分片的关系

    摘要:本文尝试对Mongo的复制和分布式事务的原理进行描述,在必要的地方,对实现的正确性进行论证,希望能为MongoDB内核爱好者提供一些参考. 1.前言 MongoDB基于wiredTiger提供的 ...

随机推荐

  1. Docker mongodb 3.4 分片 一主 一副 一仲 鉴权集群部署.

    非docker部署 为了避免过分冗余,并且在主节点挂了,还能顺利自动提升,所以加入仲裁节点 为什么要用docker部署,因为之前直接在虚拟机启动10个mongod 进程.多线程并发测试的时候,mong ...

  2. [Essay] Apache Flink:十分可靠,一分不差

    Apache Flink:十分可靠,一分不差 Apache Flink 的提出背景 我们先从较高的抽象层次上总结当前数据处理方面主要遇到的数据集类型(types of datasets)以及在处理数据 ...

  3. APP性能测试(CPU)

    获取数据 :adb shell dumpsys cpuinfo | grep packagename result = os.popen("adb shell dumpsys cpuinfo ...

  4. 【视频教程】一步步将AppBox升级到Pro版

    本系列教程分为上中下三部分,通过视频的形式讲解如何将基于FineUI(开源版)的AppBox v6.0一步一步升级FineUIPro(基础版). [视频教程]一步步将AppBox升级到Pro版(上)主 ...

  5. 企业内部DNS跨国配置案例

    背景介绍:总公司与北京分公司均由总公司进行统一管理.总公司的主从DNS担任解析总公司服务器与北京分公司的服务器解析任务.总公司DNS委派其他两个公司管理自己域下的服务器解析任务.要求任何一个节点都能解 ...

  6. Object方法

    1. getClass() 返回此 Object 的运行时类. 2. hashCode() 返回该对象的哈希码值. 3. equals() 指示其他某个对象是否与此对象“相等”. 4. toStrin ...

  7. C++ string数据类型的实现

    #include <cstdlib> #include <cstring> class Mystring { public: Mystring(const char * pda ...

  8. 一种基于主板BIOS的身份认证方案及实现

    .分析AwardBIOSDOS工具cbrom cbrom的功能就是在BIOS文件中添加.删除与提取模块,以便满足用户自己的需求,用法如下: cbromBIOS文件名/参数模块名|RELEASE|EXT ...

  9. freemarker中的split字符串分割(十六)

    1.简易说明 split分割:用来根据另外一个字符串的出现将原字符串分割成字符串序列 2.举例说明 <#--freemarker中的split字符串分割--> <#list &quo ...

  10. spring整合JMS

    浏览博客时看到大神写的,直接转载过来收藏了.原文地址:http://elim.iteye.com/blog/1893038