为什么要使用复制集

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. 实时流计算Spark Streaming原理介绍

    1.Spark Streaming简介 1.1 概述 Spark Streaming 是Spark核心API的一个扩展,可以实现高吞吐量的.具备容错机制的实时流数据的处理.支持从多种数据源获取数据,包 ...

  2. RocketMQ 单机安装

    本章快速入门指南是在本地机器上设置 RocketMQ 消息传递系统以发送和接收消息的详细说明. 在这先对RocketMQ 做一个简单介绍. RocketMQ是一个纯java.分布式.队列模型的开源消息 ...

  3. OOM问题分析

    一.背景 在实际的开发中,性能问题的分析一直是运维团队的痛点,无论是缓慢内存溢出还是迅速的内存爆炸,对系统和业务的破坏都是快速而巨大的,此贴分享下简单的分析内存问题的经验. 二.相关名词 分代:根据对 ...

  4. MySQL整理(一)

    一.数据管理发展阶段 人工管理阶段→文件系统阶段→数据库系统阶段    二.数据库管理系统提供的功能   (1)数据定义语言DDL:提供数据定义语言定义数据库及各种对象,定义数据的完整性约束和保密限制 ...

  5. 20165324 Java实验四 Android程序设计

    20165324 Java实验四 Android程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年5月1 ...

  6. python3 爬虫神器pyquery的使用实例之爬网站图片

    PyQuery 可让你用 jQuery 的语法来对 xml 进行操作,这和 jQuery 十分类似.如果利用 lxml,pyquery 对 xml 和 html 的处理将更快. 如果对 jQuery  ...

  7. DEPHI XE5 XE6 ANDROID IOS开发的几点体会

    DEPHI XE5 XE6 ANDROID IOS开发的几点体会 2014-09-04 20:48 1.不纠结于APK或者APP的大小.现在的客户端设备都很廉价,300元以上的新安卓设备都不在乎软件的 ...

  8. java中的重量级与轻量级概念

    首先轻量级与重量级是一个相对的概念,主要是对应用框架使用方便性和所提供服务特性等方面做比较的. 比方说EJB就是一个重量级的框架,因为它对所编写的代码有限制,同时它也提供分布式等复杂的功能. 相比之下 ...

  9. IDEA 编译报错: 未结束的字符串文字

    最近在搞新项目,同事用的eclipse开发,而我用的是ide,项目初始是由同事创建的,项目编码是UTF-8,而我开发的ide工具默认是GBK编码,导致在编译的时候报错: 未结束的字符串文字 这个问题就 ...

  10. GRUB2 分析 (一)

    GRUB是目前较流行启动引导程序.其第二版被主流Linux发行版所包括.本文将探索和分析GRUB的设计和实现机制. boot.S是第一个研究对象,因为boot.S将被编译成boot.img(512字节 ...