首页 > 数据库 >MongoDb副本集

MongoDb副本集

时间:2024-06-02 18:12:11浏览次数:24  
标签:副本 优先级 MongoDb 成员 oplog 数据 节点

Mongodb副本集

复制简介

复制是将数据的相同副本保留在多台服务器上的一种方法,建议将其用于所有生产部署中。即使一台或多台服务器停止运行,使用复制功能也可以确保应用程序正常运行和数据安全。

在 MongoDB 中,创建副本集(replica set)后就可以使用复制功能了。副本集是一组服务器,其中一个是用于处理写操作的主节点(primary),还有多个用于保存主节点的数据副本的从节点(secondary)。如果主节点崩溃了,则从节点会从其中选取出一个新的主节点。

如果使用复制功能时有一台服务器停止运行了,那么仍然可以从副本集中的其他服务器访问数据。如果服务器上的数据已损坏或无法访问,则可以从副本集中的其他成员中创建一份新的数据副本。

从节点可能会落后于主节点(延迟)而缺少最新的写入,所以默认情况下从节点会拒绝读请求,以防止应用程序意外读取过期数据。因此,如果尝试在从节点上查询,则会弹出一条表明它不是主节点的错误消息。这是为了防止应用程序意外地连接到从节点并读取过期数据。要是想在从节点上进行查询操作,可以设置一个“在从节点中读取是没问题的”标志

secondaryConn.setSlaveOk()

从节点不接受写操作。从节点只能通过复制功能写入数据,不接受客户端的写请求

如何设计副本集

这里先了解一下副本集中最重要的概念,即“大多数”(majority):选取主节点时需要由大多数决定,主节点只有在得到大多数支持时才能继续作为主节点,写操作被复制到大多数成员时就是安全的写操作。这里的大多数定义为“副本集中一半以上的成员”。

img

注意,副本集中有些成员停止运行或者不可用时,并不会影响“大多数”。大多数是基于副本集的配置来计算的。

假设有一个包含 5 个成员的副本集,其中 3 个成员不可用,2 个成员可以正常工作。这 2 个成员不能达到副本集大多数的要求(至少需要 3 个成员),因此它们无法选举出一个主节点。如果这 2 个成员中有一个是主节点,那么当它注意到无法得到大多数成员支持时,就会从主节点上退位。几秒后,副本集中会包含 2 个从节点和 3 个无法访问的成员。

img

为什么剩下的 2 个成员不能选举出主节点? 问题在于:其他 3 个成员实际上可能没有崩溃,而是因为网络故障而不可达,在这种情况下,左侧的 3 个成员将选举出一个主节点,因为它们可以达到副本集成员中的大多数(5 个成员中的 3 个)。在网络分区的情况下,我们不希望两边的网络各自选举出一个主节点,因为那样的话副本集就拥有 2 个主节点了。如果 2 个主节点都可以写入数据,那么整个副本集的数据就会发生混乱。只有达到“大多数”的情况下才能选举或者维持主节点,这是避免出现多个主节点的有效方式。

img

配置副本集时很重要的一点就是只能有一个主节点。例如,在拥有 5 个成员的副本集中,如果成员 1、2 和 3 位于一个数据中心,成员 4 和 5 位于另一个数据中心,那么第一个数据中心总是可以满足大多数的条件(两个数据中心之间比数据中心的内部成员之间更可能出现网络中断)。

下面是两种推荐的配置方式。

  • 将“大多数”成员放在一个数据中心,如图 10-2 所示。如果有一个主数据中心,而且你希望副本集的主节点总是位于主数据中心,那么这是一个比较好的配置。只要主数据中心正常运转,就会有一个主节点。不过,如果主数据中心不可用了,那么备份数据中心的成员将无法选举出主节点。

  • 在两个数据中心各自放置数量相等的成员,在第三个地方放置一个用于打破僵局的副本集成员。如果两个数据中心“同等”重要,那么这种配置会比较好,因为任意一个数据中心的服务器都可以找到另一台服务器以达到“大多数”。不过,这样就需要将服务器分散到 3 个地方。

如何进行选举

当一个从节点无法与主节点连通时,它就会联系并请求其他的副本集成员将自己选举为主节点。其他成员会做几项健全性检查:它们能否连接到一个主节点,而这个主节点是发起选举的节点无法连接到的?这个发起选举的从节点是否有最新数据?有没有其他更高优先级的成员可以被选举为主节点

MongoDB 在其 3.2 版本中引入了第 1 版复制协议。第 1 版协议基于斯坦福大学的 Diego Ongaro 和 John Ousterhout 开发的 RAFT 共识协议。这是一个类 RAFT 的协议[1],并且包含了一些特定于 MongoDB 的副本集概念,比如仲裁节点、优级、非选举成员、写入关注点(write concern)等。第 1 版协议提供了很多新特性的基础,比如更短的故障转移时间,以及大大减少了检测主节点失效的时间。它还通过使用 term ID 来防止重复投票。

副本集成员相互间每隔两秒发送一次心跳(heartbeat,也就是 ping)。如果某个成员在 10秒内没有反馈心跳,则其他成员会将该不良成员标记为无法访问。选举算法将尽“最大努力”尝试让具有最高优先权的从节点发起选举。成员优先权会影响选举的时机和结果。优先级高的从节点要比优先级低的从节点更快地发起选举,而且也更有可能成为主节点。然而,低优先级的从节点也可能短暂地被选为主节点,即使还存在一个可用的高优先级从节点。副本集成员会继续发起选举直到可用的最高优先级成员被选为主节点。

就所有能连接到的成员,被选为主节点的成员必须拥有最新的复制数据。严格地说,所有的操作都必须比任何一个成员的操作都要高,因此所有的操作都必须比任何一个成员的操作都要晚。

成员配置选项

优先级

优先级用于表示一个成员“渴望”成为主节点的程度。它的取值范围是 0 到 100,默认是 1。将 "priority" 设置为 0 有特殊含义:优先级为 0 的成员永远不能成为主节点。这样的成员称为被动(passive)成员。

拥有最高优先级的成员总是会被选举为主节点(只要它能连接到副本集中的大多数成员,并且拥有最新的数据)。例如,要在副本集中添加一个优先级为 1.5 的成员:

rs.add({"host" : "server-4:27017", "priority" : 1.5})

假设其他成员的优先级都是 1,只要 server-4 拥有最新的数据,当前的主节点就会自动退位,并且 server-4 会被选举为新的主节点。如果 server-4 由于某些原因未能拥有最新的数
据,那么当前主节点就会保持不变。设置优先级并不会导致副本集中无法选举出主节点,也不会使在数据同步中落后的成员成为主节点(一直到它的数据更新到最新)。

"priority" 的绝对值只与它是否大于或小于副本集中的其他优先级有关:优先级为 100、1和 1 的一组成员与优先级为 2、1 和 1 的另一组成员行为方式相同。

隐藏成员

客户端不会向隐藏成员发送请求,隐藏成员也不会优先作为副本集的数据源(尽管当其他复制源不可用时隐藏成员也会被使用)。因此,很多人会将性能较弱的服务器或者备份服务器隐藏起来。

选举仲裁者

同步

复制是指在多台服务器上保持相同的数据副本。MongoDB 实现此功能的方式是保存操作日志(oplog),其中包含了主节点执行的每一次写操作。oplog 是存在于主节点 local 数据库中的一个固定集合。从节点通过查询此集合以获取需要复制的操作。

每个从节点都维护着自己的 oplog,用来记录它从主节点复制的每个操作。这使得每个成员都可以被用作其他成员的同步源,如图 11-1 所示。从节点从同步源中获取操作,将其应用到自己的数据集上,然后再写入 oplog 中。如果应用某个操作失败(只有在基础数据已损坏或数据与主节点不一致时才会发生这种情况),则从节点会停止从当前数据源复制数据。

如果一个从节点由于某种原因而停止运行,那么当它重新启动后,就会从 oplog 中的最后一个操作开始同步。由于这些操作是先应用到数据上然后再写入 oplog,因此从节点可能会重复已经应用到其数据上的操作。MongoDB 在设计时就考虑到了这种情况:将 oplog 中的同一个操作执行多次与只执行一次效果是一样的。oplog 中的每个操作都是幂等的。也就是说,无论对目标数据集应用一次还是多次,oplog 操作都会产生相同的结果。

img

oplog 中按顺序保存着所有执行过的写操作。每个成员都维护了一份自己的 oplog,它们应该和主节点的 oplog 完全一致(可能会有一些延迟)

在大多数情况下,默认的 oplog 大小就足够了。如果预测副本集的工作负载属于以下模式之一,那么你可能会希望创建一个大于默认值的 oplog。相反,如果应用程序主要执行读操作而执行很少的写操作,那么一个较小的 oplog 就足够了。以下这些工作负载可能会需要更大的 oplog。

初始化同步

MongoDB 在执行初始化同步时,会将所有数据从副本集中的一个成员复制到另一个成员中。当一个副本集成员启动时,它会检查自身的有效状态,以确定是否可以开始从其他成员中同步数据。如果状态有效,它就会尝试从该副本集的另一个成员中复制数据的完整副本。

然而,更推荐从备份中进行恢复。从备份中恢复通常比通过mongod 复制所有的数据要快。

克隆可能会破坏同步源的工作集。在许多情况下,某些数据的子集经常会被访问,因而这部分数据总是存在于内存中(因为操作系统经常对其进行访问)。执行初始化同步会强制此成员将其所有数据分页加载到内存中,从而“驱逐”那些经常使用的数据。当那些通常由 RAM 中的数据进行处理的请求突然被迫转到磁盘时,可能此成员的速度会显著降低。不过,对于那些小型数据集和性能较好的服务器,初始化同步是一个简单易用的选择。

复制

MongoDB 执行的第二种同步是复制。从节点成员在初始化同步之后会持续复制数据。它们从同步源复制 oplog,并在一个异步进程中应用这些操作。从节点可以根据需要自动更改同步源,以应对 ping 时间及其他成员复制状态的变化。有一些规则可以控制给定节点从哪些成员进行同步。例如,拥有投票权的副本集成员不能从没有投票权的成员那里同步数据,从节点不能从延迟成员和隐藏成员那里同步数据。


  1. RAFT 是一种共识算法,它被分解成了相对独立的子问题。共识是指多台服务器或进程在一些值上达成一致的过程。RAFT 确保了一致性,使得同一序列的命令产生相同序列的结果,并在所部署的各个成员中达到相同序列的状态。 ↩︎

标签:副本,优先级,MongoDb,成员,oplog,数据,节点
From: https://www.cnblogs.com/zpf253/p/18227415

相关文章

  • Mongodb
    什么是MongoDB?MongoDB是一个基于分布式文件存储的NoSQL数据库,由C++语言编写,旨在为高性能、高可扩展性的应用提供存储支持。MongoDB将数据存储在一个类似JSON的二进制格式BSON中,这使得它非常灵活和高效。启动MongoDB服务Windows和macOS:mongod--dbpath<your_db_path>Lin......
  • MongoDB CRUD操作:批量写操作
    MongoDBCRUD操作:批量写操作文章目录MongoDBCRUD操作:批量写操作关于批量操作的顺序bulkWrite()支持的方法举例向分片集合批量插入的策略预分割集合无序写入mongos避免单调节流MongoDB提供了批量执行写入操作的能力,但批量写入操作只影响单个集合,MongoDB允许应用......
  • MongoDB CRUD操作:更新文档
    MongoDBCRUD操作:更新文档文章目录MongoDBCRUD操作:更新文档更新集合中的文档更新单个文档更新多个文档文档替换在MongoDBAtlas中更新文档更新行为原子性_id字段字段顺序Upsert选项写确认可以使用下面的方式更新MongoDB集合的文档:使用编程语言提供的驱动程序,在应......
  • 用Python脚本迁移MongoDB数据到金仓-kingbase数据库
    1、首先需要明确MongoDB与kingbase的对应关系,collection相当于table,filed相当于字段,根据这个对应关系创建表;此次迁移的MongoDB里的数据字段是:_id(自动生成的objectid),image(转成二进制存储的文档)所以在金仓里创建表createtableadmin(idvarchar,imagebytea);2、安装Python环境......
  • mongodb数据库查询调优之explain方法详解
    在MongoDB中,explain()方法可以帮助我们了解查询语句的执行计划和性能。通过分析explain()的结果,我们可以找出潜在的性能问题并对其进行优化。以下是使用explain()方法对MongoDB查询语句进行优化的步骤:使用explain()方法获取查询的执行计划:db.collection.find(query).exp......
  • 使用Java API 操作MongoDB
    除了通过启动mongo进程进入Shell环境访问数据库外,MongoDB还提供了其他基于编程语言的数据库访问方法。MongoDB官方提供了编程语言的驱动包,利用这些驱动包可以使用编程方法连接并操作MongoDB数据库。想要使用 Java程序操作 MongoDB,需要确保您的电脑上已经安装了Mong......
  • 递减 MongoDB 值,防止出现负数
    我正在使用MongoDB,我有一个文档,我想在其中递增一个计数字段。但是,我需要确保该计数不会低于零。例如,如果inc为-2,而当前计数为1,那么应用$inc将导致计数为-1,而这正是我希望避免的。以下是我当前使用的更新操作:db.collection.updateMany({'_id':{'$in':object_ids}},{......
  • MongoDb索引
    MongoDb索引数据库索引类似于图书索引。有了索引便不需要浏览整本书,而是可以采取一种快捷方式,只查看一个有内容引用的有序列表。这使得MongoDB的查找速度提高了好几个数量级。不使用索引的查询称为集合扫描,这意味着服务器端必须“浏览整本书”才能得到查询的结果。MongoDB如......
  • 深入探索 MongoDB:高级索引解析与优化策略
    MongoDB是一种非常流行的NoSQL数据库,它支持丰富的索引类型和功能,以提高数据查询的效率和性能。本文将详细介绍MongoDB的高级索引,包括基本语法、常用命令、示例、应用场景、注意事项和总结。基本语法在MongoDB中,可以使用createIndex()方法创建索引,语法如下:db.col......
  • MongoDB CRUD操作:投影Project详解
    MongoDBCRUD操作:投影Project详解文章目录MongoDBCRUD操作:投影Project详解返回文档的全部字段返回指定的字段和_id字段不输出_id字段指定排除的字段返回内嵌文档中的指定字段禁止内嵌文档中的特定字段数组中内嵌文档的投影聚合表达式的投影字段默认情况下,MongoDB查......