MongoDB复制集

news2024/11/24 11:31:19

文章目录

  • 一、介绍
    • 1、存在的意义和作用?
    • 2、需要实现啥功能?
    • 3、典型案例
    • 4、注意事项
  • 二、搭建
    • 1、安装MongoDB,配置环境变量
    • 2、创建数据目录
    • 3、配置文件
    • 4、启动 MongoDB 进程
    • 5、配置复制集
    • 6、验证
  • 三、写策略writeConcern
    • 1、w参数
    • 2、j参数
      • 2.1 介绍
      • 2.2 可选的参数值
      • 2.3 实战
    • 3、注意事项
  • 四、读策略
    • 1、readPreference
      • 1.1 可选的值
      • 1.2 适用场景
      • 1.3 Teg
      • 1.4 配置
      • 1.5实战
    • 2、readConcern
      • 2.1 可选的值
      • 2.2 majority
      • 2.3 snapshot

一、介绍

1、存在的意义和作用?

主要意义在于实现服务高可用

作用

  • 高可用:主要作用
  • 数据分发:将数据从一个区域复制到另一个区域,减少另一个区域的读延迟
  • 读写分离:不同类型的压力分别在不同的节点上执行
  • 异地容灾:在数据中心故障时候快速切换到异地

2、需要实现啥功能?

  • 数据写入时将数据迅速复制到另一个独立节点上
  • 在接受写入的节点发生故障时自动选举出一个新的替代节点

数据是如何复制的?

  • 当一个修改操作,无论是插入、更新或删除,到达主节点时,对数据的操作将被记录下来(经过一些必要的转换),这些记录称为oplog
  • 从节点通过在主节点上打开一个tailable游标不断获取新进入主节点的oplog,并在自己的数据上回放,以此保持跟主节点的数据一致

如何通过选举完成故障恢复?
复制集中最多可以有50个节点,但具有投票权的节点最多7个

  1. 具有投票权的节点之间两两互相发送心跳(2s)
  2. 当5次心跳未收到时判断为节点失联(如果失联的是主节点,从节点会发起选举,选出新的主节点;如果失联的是从节点则不会产生新的选举)
  3. 选举基于 RAFT一致性算法实现,选举成功的必要条件是大多数投票节点存活

影响选举的因素?

  • 集群存活节点大于一半
  • 被选举为主节点的节点需要具备的条件:能够与多数节点建立连接、具有较新的 oplog、具有较高的优先级

常见选项配置?

  • 是否具有投票权(v 参数):有则参与投票
  • 优先级(priority 参数):优先级越高的节点越优先成为主节点
    优先级为0的节点无法成为主节点
  • 隐藏(hidden 参数):复制数据,但对应用不可见。隐藏节点可以具有投票仅,但优先级必须为0
  • 延迟(slaveDelay 参数):复制 n 秒之前的数据,保持与主节点的时间差

3、典型案例

1主2从,最简单的复制集
备注:复制集需由3个及以上的具有投票权的节点组成

不同的节点功能?
主节点:接收写入操作,选举时投票
从节点:复制主节点上的新数据,选举时投票
投票节点:只负责投票,不存储数据,一般不推荐使用

4、注意事项

硬件的话,节点的配置必须一致,保证地位一样,另外一个就是要独立,保证不会同时宕机
软件的话,节点的版本必须一致,避免出现不兼容问题
增加节点不会增加系统写性能,可能降低写性能,这是因为需要同步,但会提高读性能

二、搭建

1、安装MongoDB,配置环境变量

这个不展开,之前介绍过,可以看入坑篇

2、创建数据目录

为3个复制集节点创建各自的数据目录,分别为data1、data2、data3

  • Linux
    mkdir -p /data/db{1,2,3}
  • Windows
    md D:\mongodb\data\db1
    md D:\mongodb\data\db2
    md D:\mongodb\data\db3

3、配置文件

复制集的每个mongod进程应该位于不同的服务器,这里我们用一台机器,要弄3个进程,配置不同的端口号即可

systemLog:
destination: file
path: D:\mongodb\data1\mongod.log # 日志文件路径
logAppend: true
storage:
dbPath: D:\mongodb\data1 # 数据目录
net:
bindIp: 0.0.0.0
port: 28017 # 端口
replication:
replSetName: forlan0

说明:

bindIp为什么是0.0.0.0?适用所有网卡,都可以访问该服务
fork表示以后台进程运行,linux可以配置
这里只展示了1台,其它两个主要改端口号和数据、日志路径

4、启动 MongoDB 进程

mongod -f D:\mongodb\data\db1\mongod.conf
mongod -f D:\mongodb\data\db2\mongod.conf
mongod -f D:\mongodb\data\db3\mongod.conf
因为 Windows 不支持 fork,以上命令需要在3个不同的窗口执行,执行后不可关闭窗口否则进程将直接结束

5、配置复制集

  • 方法1
rs.initiate()
rs.add("centosvm:28018")
rs.add("centosvm:28019")

centosvm是hostname

  • 方法2
rs.initiate({_id: "forlan0",members: [{_id: 0,host: "localhost:28017"},{_id: 1,host: "localhost:28018"},{_id: 2,host: "localhost:28019"}]})

6、验证

主节点写入

db.test.insert({ a:1 })

从节点读取

rs.slaveOk()
db.test.find()

三、写策略writeConcern

决定一个写操作落到多少个节点上才算成功

1、w参数

  • 0:发起写操作,不关心是否成功
  • 1~n:写操作需要被复制到指定节点数才算成功
    n为集群最大数据节点数;1的话,表示数据写入到Primary就向客户端发送确认,从节点采取异步线程去写
  • majority:写操作需要被复制到大多数节点上才算成功
    发起写操作的程序将阻塞,直到写操作到达指定的节点数为止
    大多数节点确认模式
    起码写到一个从节点才返回
  • all:全部节点确认模式,可能长时间阻塞

2、j参数

2.1 介绍

Journaling,类似于关系数据库中的redolog,能够使MongoDB数据库由于意外故障后快速恢复,由于提交journal日志会产生写入阻塞,所以它对写入的操作有性能影响,但对于读没有影响

MongoDB2.4版本后默认开启了Journaling日志功能,mongod实例每次启动时都会检查journal日志文件看是否需要恢复

2.2 可选的参数值

  • true:写操作落到 journal 文件中才算成功
  • false:写操作到达内存即算作成功
    在这里插入图片描述
    对于5个节点的复制集来说,写操作落到多少个节点上才算是安全的?
    至少3个节点或者配置为majority

2.3 实战

1、测试writeConcern参数

db.test.insert( {count: 1}, {writeConcern: {w: "majority"}})
db.test.insert( {count: 1}, {writeConcern: {w: 3 }})
db.test.insert( {count: 1}, {writeConcern: {w: 4 }})

2、配置延迟节点,模拟网络延迟(复制延迟)

conf=rs.conf()
conf.members[2].secondaryDelaySecs = 5   //老版本可能是conf.members[2].slaveDelay = 5
conf.members[2].priority = 0 // 不具备选举权限
rs.reconfig(conf)

观察复制延迟下的写入:执行插入操作,设置timeout参数,超时报错

db.test.insert( {count: 1}, {writeConcern: {w: 3, wtimeout:3000 }})

3、注意事项

  • 虽然多于半数的 writeConcern 都是安全的,但通常只会设置 majority,因为这是等待写入延迟时间最短的选择
  • 不要设置 writeConcern 等于总节点数,因为一旦有一个节点故障,所有写操作都将失败
  • writeConcern 虽然会增加写操作延迟时间,但并不会显著增加集群压力,因此无论是否等待,写操作最终都会复制到所有节点上
    设置 writeConcern 只是让写操作需要等待复制完成后,再返回而已
  • 重要数据应用设置{w: “majority”},以确保数据不丢失
  • 普通数据应用 设置{w: 1} ,以确保最佳性能

四、读策略

1、readPreference

解决的是,从哪里读,决定使用哪一个节点来满足正在发起的读请求

1.1 可选的值

  • primary: 只选择主节点(默认值);
  • primaryPreferred:优先选择主节点,如果不可用则选择从节点;
  • secondary:只选择从节点;
  • secondaryPreferred:优先选择从节点,如果从节点不可用则选择主节点;
  • nearest:选择最近的节点;

指定 readPreference 时也应注意高可用问题,例如将 readPreference 指定 primary,则发生故障转移不存在没有节点可读。如果业务允许,则应选择 primaryPreferred

1.2 适用场景

  • primary/primaryPreferred:用户下订单后马上将用户转到订单详情页(查询时效性要求)
  • secondary/secondaryPreferred:用户查询自己下过的订单(查询历史订单对时效性通常没有太高要求)
  • secondary:生成报表,对时效性要求不高,但资源需求大,可以在从节点单独处理,避免对线上用户造成影响
  • nearest:将用户上传的图片分发到全世界,让各地用户能够就近读取(每个地区的应用选择最近的节点读取数据)

1.3 Teg

作用?
因为readPreference 只能控制使用一类节点,而它可以选择控制到一个或几个节点

场景?
一个 5 个节点的复制集:

  • 3 个节点硬件较好,专用于服务线上客户
  • 2 个节点硬件较差,专用于生成报表

所以可以使用 Tag 来达到这样的控制目的,在线应用读取时指定{purpose: “online”},报表读取时指定 {purpose: “analyse”}

1.4 配置

  • 通过 MongoDB 的连接串参数
    xxx?replicaSet=rs&readPreference=secondary
  • 通过 MongoDB 驱动程序 API
    MongoCollection.withReadPreference(ReadPreference readPref)
  • Mongo Shell
    db.collection.find({}).readPref(“secondary”)

1.5实战

主节点写入 {x:1}, 观察该条数据在各个节点均可见

db.test.drop()
db.test.insert({x:1})

在两个从节点分别执行 db.fsyncLock() 来锁定写入(同步)

db.fsyncLock()

主节点写入 {x:2}

db.test.insert({x:2})

主节点上看到有2条数据
从节点上看到只有1条数据
解除从节点锁定 db.fsyncUnlock()
在从节点上看,可以看到同步的数据了

db.test.find().readPref("secondary")

2、readConcern

解决的是,什么数据可以读

决定这个节点上的数据哪些是可读的,类似于关系数据库的隔离级别

2.1 可选的值

有事务要求,使用snapshot,否则使用majority

  • available
    读取所有可用的数据
  • local
    读取所有可用且属于当前分片的数据
  • majority
    读取在大多数节点上提交完成的数据
  • linearizable
    可线性化读取文档
  • snapshot
    读取最近快照中的数据

2.2 majority

只读取大多数据节点上都提交了的数据
如何实现?
节点上维护多个 x 版本,MVCC 机制,通过维护多个快照来链接不同的版本

  • 每个被大多数节点确认过的版本都将是一个快照
  • 快照持续到没有人使用为止才被删除

实战:
1、安装 3 节点复制集(一主两从)
2、配置文件内 server 参数 enableMajorityReadConcern
在这里插入图片描述
3、将复制集中的两个从节点使用 db.fsyncLock() 锁住写入(模拟同步延迟)

db.test.save({"x":1})
db.test.find().readConcern("local")
db.test.find().readConcern("majority")

解锁后就正常了

结论:
写操作在没到达大多数节点前,主节点挂了,写操作就丢失了,操作回滚,可以理解为事务,只不过是大多数节点成功才提交,所以可以避免脏读

2.3 snapshot

只在多文档事务中生效,类似隔离级别,不可重复读

测试:
1、准备数据

db.tx.insertMany([{ x: 1 }, { x: 2 }]);

2、事务操作

var session = db.getMongo().startSession();
session.startTransaction();
var coll = session.getDatabase('test').getCollection("tx");
coll.updateOne({x: 1}, {$set: {y: 1}});
coll.findOne({x: 1});
db.tx.findOne({x: 1});
session.abortTransaction();

事务内操作db.tx.findOne({x: 1}),得到值 {x:1, y:1}
事务外操作db.tx.findOne({x: 1}),得到值 {x:1}

3、可重复读Repeatable Read,事务操作

var session = db.getMongo().startSession();
session.startTransaction({readConcern: {level: "snapshot"},writeConcern: {w: "majority"}});
var coll = session.getDatabase('test').getCollection("tx");
coll.findOne({x: 1}); 
db.tx.updateOne({x: 1}, {$set: {y: 1}});
db.tx.findOne({x: 1});
coll.findOne({x: 1}); 
session.abortTransaction();

两次读取结果一样,如下:
在这里插入图片描述

注意事项

  • 事务默认必须在 60 秒(可调)内完成,否则将被取消
  • 涉及事务的分片不能使用仲裁节点
  • 事务会影响 chunk 迁移效率。正在迁移的 chunk 也可能造成事务提交失败(重试即可)
  • 多文档事务中的读操作必须使用主节点读
  • readConcern 只应该在事务级别设置,不能设置在每次读写操作上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/752509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《如何使用思维导图进行知识结构的建立和扩展》

I.思维导图作为知识管理工具的重要性 思维导图是一款强大的效率工具,可以帮助有效的管理知识。”一图胜千言“它用图形的方式,将各个主题连接起来。我们可以清晰的了解到各主题之间的关系。 在知识管理中,通过创建一个知识主题的中心&#xf…

PVE虚拟化平台之安装Ubuntu-server系统

PVE虚拟化平台之安装Ubuntu-server系统 一、Ubuntu介绍1.1 Ubuntu简介1.2 Ubuntu版本1.3 ubuntu命名规则 二、上传镜像到PVE存储2.1 检查PVE环境2.2 上传镜像 三、创建虚拟机3.1 设置虚拟机名称3.2 操作系统设置3.3 系统设置3.4 磁盘设置3.5 cpu设置3.6 内存设置3.7 网络设置3.…

libvirt 热迁移流程及参数介绍

01 热迁移基本原理 1.1 热迁移概念 热迁移也叫在线迁移,是指虚拟机在开机状态下,且不影响虚拟机内部业务正常运行的情况下,从一台宿主机迁移到另外一台宿主机上的过程。 1.2 虚拟机数据传输预拷贝和后拷贝 预拷贝(pre-copy): …

3、wampserver中查看各项当前版本及简单配置PHP

wampserver点击左键,即可查看Apache,PHP,MySQL,MariaDB的当前版本 在wampserver的安装目录中,在相应的D:\wamp64\bin\php\php8.0.26 php.ini文件中,short_open_tag On(是否允许使用 PHP代码开…

在新建环境下配置低版本opencv

我这边是要解决 python报错:AttributeError: ‘module’ object has no attribute xfeatures2d’的问题, xfeatures2d在新版本已经被取消,但是需要使用老版本的一个函数 确定opencv与python的版本对应关系 一般来说可以对照这个表 具体来说…

Mac下安装python使用TensorFlow训练自己的模型

程序猿日常 Mac下安装python使用TensorFlow训练自己的模型目标 https://www.tensorflow.org/lite/models/modify/model_maker/image_classification?hlzh-cn 安装Python3.8版本 下载地址双击安装 安装pip curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py pyth…

ZKML:区块链世界的AI+隐私

1. 引言 本文主要参考: 2023年6月drCathieSo.eth 与 Ethereum Malaysia 视频 ZKML: Verifiable & Privacy-Preserving Compute in Blockchain2023年6月drCathieSo.eth 与 PSE 视频 Folding Circom circuits: a ZKML case study - Dr. Cathie So ZKML&#xf…

解决SpringMVC中@ResponseBody返回中文乱码

错误 解决方案一 Controller中的注解采用如下方式&#xff1a; GetMapping(value "/init" ,produces "application/json;charsetutf-8")这种方式仅对设置了的方法有效。 解决方案二 在applicationContext.xml中添加如下代码&#xff1a; <!-- 解…

广播与组播

目录 一、广播1. 什么是广播&#xff1f;2. 广播的实现 二、组播1. 分类的IP地址2. 多播IP地址3. 组播的实现 广播与组播和实现UDP通信的代码差不多 一、广播 1. 什么是广播&#xff1f; 数据包发送方式只有一个接受方&#xff0c;称为单播 如果同时发给局域网中的所有主机&…

解决vite+vue3打包部署到非根目录路径问题

修改vite.config.js文件&#xff0c;base为部署路径 base配置选项&#xff1a;

vue3 my-cron-vue3插件的使用

my-cron-vue3 这是一个cron表达式生成插件,基于vue3.0与element-plus实现。 npm i my-cron-vue3//前置配置 import { createApp } from vue import ElementPlus from element-plus; import element-plus/lib/theme-chalk/index.css; import App from ./App.vue //全局引入 imp…

探索华为、思科和瞻博网络的基本ACL和高级ACL配置方法

在网络安全中&#xff0c;访问控制列表&#xff08;Access Control List&#xff0c;简称ACL&#xff09;是一种重要的工具&#xff0c;用于控制数据包在网络中的流动。多家网络设备厂商提供了各自的ACL配置方法&#xff0c;其中华为、思科和瞻博网络是备受认可和使用广泛的品牌…

(中等)LeetCode 剑指OfferII 074. 合并区间

排序&#xff1a; 用数组merged存储最终的答案 首先&#xff0c;将列表中的区间按照左端点升序排序&#xff0c;将第一个区间加入merged数组中&#xff0c;并按顺序依次考虑之后的每个区间&#xff1a; 如果当前区间的左端点在数组merged中最后一个区间的右端点之后&#xf…

ChatGPT提问的万能公式,强烈建议收藏!泰裤辣!

在实际使用GPT的时候&#xff0c;并不是GPT不够强大&#xff0c;而是我们需要很多时间去调教AI&#xff0c;以便输出我们期望的答案&#xff0c;为了让输出无限的靠近你的期望&#xff0c;就需要下面这个万能的框架&#xff0c;如果大家记不住这个框架或者没有形成习惯&#xf…

nginx相关

1、nginx无默认配置文件 参考文章&#xff1a;nginx配置失败&#xff0c;卸载后重装无 nginx.conf文件_haojuntu的博客-CSDN博客 2、nginx更改服务器的端口号 参考文章&#xff1a;https://www.cnblogs.com/chaosfe/p/16123585.html#:~:text%E6%88%91%E4%BB%AC%E6%9F%A5%E7%…

【雕爷学编程】Arduino动手做(149)---MAX9814咪头传感器模块7

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

​LeetCode解法汇总​979. 在二叉树中分配硬币

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 给定一个有 N 个结点的二叉树的根结点 root&#xff0c;树中的每个结点上都对应…

从0到1学习Yalmip工具箱(2)-决策变量进阶

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译&#xff1a;https://yalmip.github.io/tutorials/ 1.决策变量的定义 1.1 sdpvar 上文简单介绍了sdpvar函数的用法&#xff0c;接下来将对其进行详细介绍。复习一下&#xff0c;sdpvar函数的基本语…

模板方法模式:简化代码,提高复用性

在软件开发中&#xff0c;我们经常会遇到一些算法或业务流程&#xff0c;其中的步骤或顺序是固定的&#xff0c;但某些步骤的具体实现方式可能会有所不同。这时&#xff0c;模板方法模式就能派上用场。模板方法模式是一种行为设计模式&#xff0c;它定义了一个算法的骨架&#…

环肽科研试剂:161552-03-0,Cyclo(-Arg-Gly-Asp-D-Phe-Lys),IC50为0.94nM

资料编辑|陕西新研博美生物科技有限公司小编MISSwu 五元环肽Cyclo(-Arg-Gly-Asp-D-Phe-Lys) &#xff08;CAS号&#xff1a;161552-03-0&#xff09;&#xff0c;是αvβ3整联蛋白的有效和选择性抑制剂&#xff0c;IC50为0.94nM。可以高放射化学纯度&#xff08;>97&#xf…