52.MongoDB复制(副本)集实战及其原理分析

这篇具有很好参考价值的文章主要介绍了52.MongoDB复制(副本)集实战及其原理分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MongoDB复制集架构

高可用

在生产环境中,不建议使用单机版的MongoDB服务器。

Mongodb复制集(Replication Set)由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持复制集内所有成员存储相同的数据集,提供数据的高可用。复制集提供冗余和高可用性,是所有生产部署的基础。它的现实依赖于两个方面的功能:

  • 数据写入时将数据迅速复制到另一个独立节点上

  • 在接受写入的节点发生故障时自动选举出一个新的替代节点

三节点复制集模式

PSS模式(官方推荐模式)

PSS模式由一个主节点和两个备节点所组成,即Primary+Secondary+Secondary。

PSA模式

PSA模式由一个主节点、一个备节点和一个仲裁者节点组成,即Primary+Secondary+Arbiter

安全认证

 #mongo.key采用随机算法生成,用作节点内部通信的密钥文件。
 openssl rand -base64 756 > /data/mongo.key
 #权限必须是600
 chmod 600 /data/mongo.key  
 # 启动mongod
 mongod -f /data/db1/mongod.conf --keyFile /data/mongo.key

复制集连接方式

通过高可用 Uri 的方式连接 MongoDB,当 Primary 故障切换后,MongoDB Driver 可自动感知并把流量路由到新的 Primary 节点

mongosh mongodb://fox:fox@192.168.139.135:27017,192.168.139.136:27017,192.168.139.137:27017/admin?replicaSet=rs0

复制集成员角色

成员角色的属性

Priority = 0 当 Priority 等于 0 时,它不可以被复制集选举为主,Priority 的值越高,则被选举为主的概率更大。通常,在跨机房方式下部署复制集可以使用该特性。假设使用了机房A和机房B,由于主要业务与机房A更近,则可以将机房B的复制集成员Priority设置为0,这样主节点就一定会是A机房的成员。

Vote = 0 不可以参与选举投票,此时该节点的 Priority 也必须为 0,即它也不能被选举为主。由于一个复制集中最多只有7个投票成员,因此多出来的成员则必须将其vote属性值设置为0,即这些成员将无法参与投票。

成员角色

  • Primary:主节点,其接收所有的写请求,然后把修改同步到所有备节点。一个复制集只能有一个主节点。

  • Secondary:备节点,与主节点保持同样的数据集。当主节点“挂掉”时,参与竞选主节点。分为以下三个不同类型:

    • Hidden = false:正常的只读节点,是否可选为主,是否可投票,取决于 Priority,Vote 的值;
    • Hidden = true:隐藏节点,对客户端不可见, 可以参与选举,但是 Priority 必须为 0,即不能被提升为主。 由于隐藏节点不会接受业务访问,因此可通过隐藏节点做一些数据备份、离线计算的任务,这并不会影响整个复制集。
    • Delayed :延迟节点,必须同时具备隐藏节点和Priority0的特性,会延迟一定的时间(secondaryDelaySecs 配置决定)从上游复制增量,常用于快速回滚场景。
  • Arbiter:仲裁节点,只用于参与选举投票,本身不承载任何数据,只作为投票角色。比如你部署了2个节点的复制集,1个 Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加⼀个 Arbiter节点,即使有节点宕机,仍能选出Primary。 Arbiter本身不存储数据,是非常轻量级的服务,当复制集成员为偶数时,最好加入⼀个Arbiter节点,以提升复制集可用性。

#配置隐藏节点
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
rs.reconfig(cfg)

#配置延时节点
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
#延迟1分钟
cfg.members[1].secondaryDelaySecs = 60
rs.reconfig(cfg)

#添加投票节点
# 为仲裁节点创建数据目录,存放配置数据。该目录将不保存数据集
mkdir /data/arb
# 启动仲裁节点,指定数据目录和复制集名称
mongod --port 30000 --dbpath /data/arb --replSet rs0 
# 进入mongo shell,添加仲裁节点到复制集
rs.addArb("ip:30000")
# 执行命令
db.adminCommand( {"setDefaultRWConcern" : 1, "defaultWriteConcern" : { "w" : 2 } } )


#移除复制集节点
rs.remove("ip:port")
#通过 rs.reconfig() 来移除节点
cfg = rs.conf()
cfg.members.splice(2,1)  #从2开始移除1个元素
rs.reconfig(cfg)

#更改复制集节点
cfg = rs.conf()
cfg.members[0].host = "ip:port"
rs.reconfig(cfg)


MongoDB复制集原理

数据同步

MongoDB的复制集选举使用Raft算法(https://raft.github.io/)来实现,选举成功的必要条件是大多数投票节点存活。

MongoDB对raft协议添加了一些自己的扩展

  • 支持chainingAllowed链式复制,即备节点不只是从主节点上同步数据,还可以选择一个离自己最近(心跳延时最小)的节点来复制数据。
  • 增加了预投票阶段,即preVote,这主要是用来避免网络分区时产生Term(任期)值激增的问题
  • 支持投票优先级,如果备节点发现自己的优先级比主节点高,则会主动发起投票并尝试成为新的主节点。

一个复制集最多可以有50 个成员,但只有 7 个投票成员。

自动故障转移

一个影响检测机制的因素是心跳,在复制集组建完成之后,各成员节点会开启定时器,持续向其他成员发起心跳,这里涉及的参数为heartbeatIntervalMillis,即心跳间隔时间,默认值是2s。如果心跳成功,则会持续以2s的频率继续发送心跳;如果心跳失败,则会立即重试心跳,一直到心跳恢复成功。

一个影响检测机制的因素是心跳,在复制集组建完成之后,各成员节点会开启定时器,持续向其他成员发起心跳,这里涉及的参数为heartbeatIntervalMillis,即心跳间隔时间,默认值是2s。如果心跳成功,则会持续以2s的频率继续发送心跳;如果心跳失败,则会立即重试心跳,一直到心跳恢复成功。

在electionTimeout任务中触发选举必须要满足以下条件

(1)当前节点是备节点。

(2)当前节点具备选举权限。

(3)在检测周期内仍然没有与主节点心跳成功。

业务影响评估

  • 在复制集发生主备节点切换的情况下,会出现短暂的无主节点阶段,此时无法接受业务写操作。
  • 对于非常重要的业务,建议在业务层面做一些防护策略,比如设计重试机制。
# MongoDB Drivers 启用可重试写入
mongodb://localhost/?retryWrites=true
# mongo shell
mongosh --retryWrites

如何优雅的重启复制集

  • 逐个重启复制集里所有的Secondary节点
  • 对Primary发送rs.stepDown()命令,等待primary降级为Secondary
  • 重启降级后的Primary

复制集数据同步机制

MongoDB oplog 是 Local 库下的一个集合,用来保存写操作所产生的增量日志(类似于 MySQL 中 的 Binlog)。

primary ---------- write ----------》 local.oplog.rs ---------- read----------》secondary ---------- write ----------》 local.oplog.rs

​ ---------- read----------》secondary ---------- write ----------》 local.oplog.rs

oplog 中的 ts 是备节点实现增量日志同步的关键

每个备节点都分别维护了自己的一个offset,也就是从主节点拉取的最后一条日志的optime,在执行同步时就通过这个optime向主节点的oplog集合发起查询。

MongoDB在4.0版本之后提供了replSetResizeOplog命令,可以实现动态修改oplogSize而不需要重启服务器。

# 将复制集成员的oplog大小修改为60g  
db.adminCommand({replSetResizeOplog: 1, size: 60000})
# 查看oplog大小
use local
db.oplog.rs.stats().maxSize

幂等性

某文档x字段当前值为100,用户向Primary发送一条{KaTeX parse error: Expected 'EOF', got '}' at position 12: inc: {x: 1}}̲,记录oplog时会转化为一条…set: {x: 101}的操作,才能保证幂等性。

幂等性的代价 : oplog的写入被放大,导致同步追不上

使用数组时,尽量注意:

  1. 数组的元素个数不要太多,总的大小也不要太大
  2. 尽量避免对数组进行更新操作
  3. 如果一定要更新,尽量只在尾部插入元素,复杂的逻辑可以考虑在业务层面上来支持

复制延迟

为了尽量避免复制延迟带来的风险,我们可以采取一些措施

  • 增加oplog的容量大小,并保持对复制窗口的监视。
  • 通过一些扩展手段降低主节点的写入速度。
  • 优化主备节点之间的网络。
  • 避免字段使用太大的数组(可能导致oplog膨胀)。

数据回滚

mongorestore --host 192.168.192:27018 --db test --collection emp -ufox -pfox 
--authenticationDatabase=admin rollback/emp_rollback.bson

同步源选择

在settings.chainingAllowed开启的情况下,备节点自动选择一个最近的节点(ping命令时延最小)进行同步。文章来源地址https://www.toymoban.com/news/detail-734603.html

#默认情况下备节点并不一定会选择主节点进行同步,这个副作用就是会带来延迟的增加,可以通过以下命令关闭
cfg = rs.config()
cfg.settings.chainingAllowed = false
rs.reconfig(cfg)

#使用replSetSyncFrom命令临时更改当前节点的同步源
db.adminCommand( { replSetSyncFrom: "hostname:port" })

到了这里,关于52.MongoDB复制(副本)集实战及其原理分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MongoDB副本集搭建

    版本 集群相关命令 参考 配置文件 集群配置 初始化 在主节点上执行命令如下: 添加成员节点 检查和测试

    2024年02月09日
    浏览(33)
  • 使用 docker 创建 mongodb 副本集, 和调整副本集优先级

    === mongod 本地创建副本集 mongod --port 27017 --dbpath /srv/mongodb/db0 --replSet rs0 --bind_ip localhost,hostname(s)|ip address(es) –dbpath 指向数据存放地址 –replSet 后面为 副本集的名。 rs.initiate() 启动新的副本集 rs.conf() 查看副本集的配置 rs.status() 查看副本集的状态 rs.add() 将成员添加到副本集

    2024年02月09日
    浏览(41)
  • 1. MongoDB快速实战与基本原理

    本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。 课程内容: 1.MongoDB优势及其应用场景分析 2.MongoDB安装文档操作 3.MongoDB数据模型详解 4.MongoDB固定集合实战 5.基于WiredTiger存储引擎读写模型详解 MongoDB4.0之后支持复制集的多文档事务,

    2024年02月11日
    浏览(27)
  • 搭建 MongoDB (v6.0) 副本集记录

    副本集(Replica Set)是一组带有故障转移的 MongoDB 实例组成的集群,由一个主(Primary)服务器和多个从(Secondary)服务器构成。通过Replication,将数据的更新由Primary推送到其他实例上,在一定的延迟之后,每个MongoDB实例维护相同的数据集副本。通过维护冗余的数据库副本,能

    2024年02月05日
    浏览(50)
  • Mongodb Replica Sets 副本集群搭建

    Replica Sets 复制集搭建 MongoDB 有三种集群架构模式,分别为主从复制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式。 Master-Slaver 是一种主从复制的模式,目前已经不推荐使用 ReplicaSet模式取代了Master-Slaver模式,是一种互为主从的关系。Replica Set 将数据复制多份保存

    2024年01月22日
    浏览(53)
  • MongoDB 7.0 搭建 Sharding 副本集群

    本文是在ubuntu 22.03 系统版本上部署的,最低支持mongodb-6.0.4以上,所以这里安装mongodb7.0 安装方式有多种,本人是使用的第一种方式,时间也就20分钟吧,能接受。 S1.导入 MongoDB GPG 公钥,用于验证下载的软件包的完整性,使用以下命令导入公钥 具体需要导入的版本号,可以去

    2024年02月19日
    浏览(41)
  • 【保姆级教程】:docker搭建MongoDB三节点副本集

    欢迎关注公众号:天天说编程 你的关注是我最大的动力! 容器可以理解为一个进程,镜像是把环境,组件等都配置好,运行成容器的,容器里面运行服务,也可以说是一个进程。镜像是模板,镜像是实例。 一个镜像可以创建多个实例。也就是多个容器,容器之间相互独立。

    2024年02月03日
    浏览(46)
  • Redis 事务、持久化、复制原理分析

    Redis是一种高性能的键值存储数据库,同时也是一种基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 Redis的事务机制提供了一种原子性地执行多个命令的方式,在同时发生多个 Redis 命令时,可以使用事务来确保它们都会被执行。 Redis的持久化机制可以

    2024年02月13日
    浏览(41)
  • Python强化学习实战及其AI原理详解

      时间循环是一类热门的影视题材,其设定常常如下:主人公可以主动或被动的回到过去。与此同时,主人公会希望利用这样的机会改变在之前的经历中不完美的结果。为此,主人公调整自己的行为,使得结果发生变化。   一些和时间循环有关的电影:例如,时间循环电

    2024年02月04日
    浏览(44)
  • SpringBoot整合RabbitMQ及其原理分析

    上一篇:RabbitMQ基础知识 这里无需指定版本号,让其跟着SpringBoot版本走。本示例使用SpringBoot版本号为2.7.10。 创建两个SpringBoot应用,模拟消息生产者与消费者【publisher、consumer】。 编写配置文件, 用户名和密码等自行修改 这里虚拟机的名称是上一篇文章中新建的。 声明交换

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包