为什么要使用复制集

1.备份数据
通过自带的 mongo_dump/mongo_restore 工具也可以实现备份,但是毕竟没有复制集的自动同步备份方便。

2.故障自动转移
部署了复制集,当主节点挂了后,集群会自动投票再从节点中选举出一个新的主节点,继续提供服务。而且这一切都是自动完成的,对运维人员和开发人员是透明的。当然,发生故障了还是得人工及时处理,不要过度依赖复制集,万一都挂了,那就连喘息的时间都没有了。

3.在某些特定的场景下提高读性能
默认情况下,读和写都只能在主节点上进行。
下面是MongoDB的客户端支持5种复制集读选项:

  • primary:默认模式,所有的读操作都在复制集的 主节点 进行的。

  • primaryPreferred:在大多数情况时,读操作在 主节点 上进行,但是如果主节点不可用了,读操作就会转移到 从节点 上执行。

  • secondary:所有的读操作都在复制集的 从节点 上执行。

  • secondaryPreferred:在大多数情况下,读操作都是在 从节点 上进行的,但是当 从节点 不可用了,读操作会转移到 主节点 上进行。

  • nearest:读操作会在 复制集 中网络延时最小的节点上进行,与节点类型无关。

来源:http://docs.mongoing.com/manual-zh/core/read-preference.html

不推荐在从节点上进行读操作,因为从节点上的数据可能不是最新数据(主要原因)。
在从节点上进行读操作的场景很有限,官方手册中写明了适用的场景和不推荐从节点读操作的多个原因:http://docs.mongoing.com/manual-zh/core/read-preference.html#use-cases

说说我自己的看法:复制集并不是为了提高读性能而存在的,除了个别场景,不推荐在从节点上进行读操作。如果想提升读性能,那么请使用索引和分片。插一句,如果数据规模不大,就没必要使用分片了。我们线上数据库中单个集合记录有将近 2 亿条,性能还比较 OK(当然,机器配置也不差,而且上面就只跑了一个 Redis 和一个 MongoDB)。

如何部署复制集

请看手册:http://docs.mongoing.com/manual-zh/tutorial/deploy-replica-set.html

如何在程序中使用 MongoDB 复制集故障自动转移的特性

以 PHP 的 mongo 驱动为例。

$client = new MongoClient('mongodb://192.168.1.2:27018,192.168.1.3:27019,192.168.1.4:27020', array('replicaSet' => 'rs0'));

这样配置后,如果只是其中一台 MongoDB 服务挂断后,剩余的节点会自动选举出新的主节点,程序还是可以继续正常运行。在选举的过程中,程序还是会抛出异常的,尽管选举过程很快,但是为了程序的健壮性,必须考虑异常的处理。当然,如果选举不出新的主节点,那么整个 MongoDB 就不可用了。(根据上面讲的,如果复制集的读选项是配置的 primaryPreferred。如果没有了主节点,但是从节点还可用的话,那么读操作将转移到从节点上去,这样整个 MongoDB 复制集还能提供读操作服务)

其实如果指定了复制集名 'replicaSet' => 'rs0',那么就算不列出所有节点地址,仅写一个有效节点地址,mongo 驱动会自动获取到所有有效节点,$client->getHosts() 方法可以查看所有有效节点的地址。

但是如果你只写了一个节点地址,刚好是那个节点挂掉了,那就连不上了。所有我建议配置完整的节点地址列表

同步的原理是什么

开启复制集后,会在 local 库下生成一个集合叫 oplog.rs,这是一个有限集合,也就是大小是固定的。每次对数据库的写操作都会被记录到这个集合里面。复制集中的节点就是通过读取其他节点上面的 oplog 来实现数据同步的。

举个例子:
用客户端向主节点添加了 100 条记录,那么 oplog 中也会有这 100 条的 insert 记录。从节点通过获取主节点的 oplog,也执行这 100 条 oplog 记录。这样,从节点也就复制了主节点的数据,实现了同步。

需要说明的是:并不是从节点只能获取主节点的 oplog。

为了提高复制的效率,复制集中所有节点之间会互相进行心跳检测(通过ping)。每个节点都可以从任何其他节点上获取oplog。

还有,用一条语句批量删除 50 条记录,并不是在 oplog 中只记录一条数据,而是记录 50 条单条删除的记录。

oplog中的每一条操作,无论是执行一次还是多次执行,对数据集的影响结果是一样的,i.e 每条oplog中的操作都是幂等的。

什么情况下需要重新同步

在上一个问题中得知:oplog 大小是固定的,而且 oplog 里面的记录数不一定和节点中的数据量成正比。那么,新记录肯定会将前面的老记录给覆盖。

如果,有天一个从节点挂了,其他节点还在正常运行,继续有写操作,oplog 继续增长。而这个挂掉的节点一直不能从其他节点那里同步最新的 oplog 记录,当其他节点的 oplog 已经发生的覆盖。即使这个从节点后来恢复了正常,也不会和其他节点保持数据一致了。因为,覆盖的就永远回不来了。

那么,这个时候就得重新同步了。恩,回不去的就永远回不去了,再找个新的重新开始吧。(逃

如何重新同步

参见:复制集成员的重新同步

什么时候应该使用投票节点

当复制集中有偶数个节点时,应该再加一个投票节点,用于打破投票僵局。

比如:我线上共有3台服务器,其中1台是作为 Web 服务器;其余2台作为 DB 服务器,各部署了1个MongoDB节点,构成了2个节点的复制集。这个时候,我并没有多余的机器了。在这个情况下,如果任意一台 DB 服务器上的 MongoDB 挂了,那么另外一台的 MongoDB 必然变为 SECONDARY 节点,那么就意味着 MongoDB 是不可用的了。为了避免这种情况,提高服务的可用性,可以在 Web 服务器上部署一个投票节点。投票节点并不存储数据,因此不能升职为 PRIMARY 节点,它对于硬件资源要求很低,并不会对 Web 服务器上的其他程序产生太大影响。这种情况下,如果任意一台 DB 服务器挂了,另外一台服务器上的 MongoDB 将成为 PRIMARY 节点,此时 MongoDB 还是依旧对外提供服务的。乘此时机,赶紧排查出故障的那台服务器的原因,尽快恢复服务。

为了让投票节点可以占用更少的资源,可以在配置文件中添加以下几个配置项:

journal = false
smallfiles = true
noprealloc = true

主从复制

master-slave 复制架构已经不推荐使用了,建议使用 replica sets 复制集架构。
参见:http://docs.mongoing.com/manual-zh/core/master-slave.html

复制集节点状态statestr

  • STARTUP:刚加入到复制集中,配置还未加载
  • STARTUP2:配置已加载完,初始化状态
  • RECOVERING:正在恢复,不适用读
  • ARBITER: 仲裁者
  • DOWN:节点不可到达
  • UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂
  • REMOVED:移除复制集
  • ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
  • FATAL:出错。查看日志grep “replSet FATAL”找出错原因,重新做同步
  • PRIMARY:主节点
  • SECONDARY:备份节点

来源:https://segmentfault.com/a/1190000004025139

关于 MongoDB 复制集的更多相关文章

  1. MongoDB 复制集 (一) 成员介绍

       一 MongoDB 复制集简介          MongoDB的复制机制主要分为两种:          Master-Slave    (主从复制)      这个已经不建议使用       ...

  2. mongodb 复制集

    mongodb 复制集 复制集简介 Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写 ...

  3. Raft与MongoDB复制集协议比较

    在一文搞懂raft算法一文中,从raft论文出发,详细介绍了raft的工作流程以及对特殊情况的处理.但算法.协议这种偏抽象的东西,仅仅看论文还是比较难以掌握的,需要看看在工业界的具体实现.本文关注Mo ...

  4. MongoDB复制集

    1.1 MongoDB复制集简介 一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合.复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础. 1.1.1 复制集的目的 ...

  5. MongoDB复制集原理、环境配置及基本测试详解

    一.MongoDB复制集概述 MongoDB复制集实现了冗余备份和故障转移两大功能,这样能保证数据库的高可用性.在生产环境,复制集至少包括三个节点,其中一个必须为主节点,一个从节点,一个仲裁节点.其中 ...

  6. MongoDB复制集技术

    复制集搭建 没毛病: https://www.cnblogs.com/nicolegxt/p/6841442.html?utm_source=itdadao&utm_medium=referr ...

  7. mongodb复制集Replica Set使用简介

    MongoDB高可用 对于MongoDB,可以支持使用单机模式提供服务,但是在实际的生产环境中,单机模式将面临很大的风险,一旦这个数据库服务出现问题,就会导致线上的服务出现错误甚至崩溃.因此,在实际生 ...

  8. MongoDB复制集的工作原理介绍(二)

    复制集工作原理 1)数据复制原理 开启复制集后,主节点会在 local 库下生成一个集合叫 oplog.rs,这是一个有限集合,也就是大小是固定的.其中记录的是整个mongod实例一段时间内数据库的所 ...

  9. MongoDB复制集成员及状态转换

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 复制集(Replica Set)是MongoDB核心组件,相比早期版本采用的主从(Master-Slave) ...

  10. 部署MongoDB复制集(副本集)

    环境 操作系统:Ubuntu 18.04 MongoDB: 4.0.3 服务器 首先部署3台服务器,1台主节点 + 2台从节点 3台服务器的内容ip分别是: 10.140.0.5 (主节点) 10.1 ...

随机推荐

  1. SQL学习笔记。

    数据库视图: 视图是虚表,是从一个或几个基本表(或视图)中导出的表,在系统的数据字典中仅存放了视图的定义,不存放视图对应的数据. 视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式.可以将视 ...

  2. django之自定义软删除Model

    软删除 简单的说,就是当执行删除操作的时候,不正真执行删除操作,而是在逻辑上删除一条记录.这样做的好处是可以统计数据,可以进行恢复操作等等. 预备知识 Managers Managers 是djang ...

  3. .def文件如何编写

    DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport),这里不再举例说明:另外一种方式是采用模块定义(.def) 文件声明. 规则是:1.首先创建 一个DL ...

  4. python全栈开发从入门到放弃之迭代器生成器

    1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable  可迭代的 可迭 ...

  5. Embedding SQLite in a c programm

    Embedding SQLite in a c programm        The following program demonstrates how to embed SQLite into ...

  6. Springboot 日志管理配置logback-spring.xml

    几种常见的日志 Log4j:是最早的日志框架,是apach旗下的,可以单独使用,也可配合日志框架JCL使用: Log4j2:apach旗下的关于log4j的升级版: Logback:是基于slf4j接 ...

  7. webpack.dev.conf.js详解

    转载自:https://www.cnblogs.com/ye-hcj/p/7087205.html webpack.dev.conf.js详解 //引入当前目录下的utils.js文件模块var ut ...

  8. nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)解决

    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 报错信息 nginx: [emerg] bind() t ...

  9. 如何获取iClap的内测资格

    iClap,一款拥有智能产品管理能力的系统,第一次遇见是在8月下旬的创新中国的展会上,茫茫人海中只因多看了你一眼,便深深的留在脑海里挥之不去,展会结束的当天就忍不住想要更多的了解你,登陆iClap官网 ...

  10. Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) D - Dynamic Problem Scoring

    地址:http://codeforces.com/contest/807/problem/D 题目: D. Dynamic Problem Scoring time limit per test 2 ...