MongoDB 单节点升级为副本集高可用集群(1主1从1仲裁)

news2024/11/16 18:52:50
作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)
公众号:老苏畅谈运维
欢迎关注本人公众号,更多精彩与您分享。

一、项目背景

由于历史原因,生产环境中MongoDB使用的是单节点。但随着业务增长,考虑到这个同步业务的重要性,避免由于单节点故障造成业务停止,所以需要升级为副本集保证高可用。
下面这架构图是需要实现的MongoDB副本集高可用架构:
请添加图片描述
Relica Set副本集方式整体大概如图:
请添加图片描述

二、 升级架构前注意事项

在生产环境中,做单节点升级到集群前,一定要先备份好mongodb的所有数据,避免操作失误导致数据丢失。
并且在保证在升级期间不会有程序连接到MongoDB进行读写操作,建议停服务升级,且在凌晨业务低峰期,进行操作。

–使用mongodump进行全库备份

mongodump  -uroot -p123456 --port 27017 --authenticationDatabase admin -j 2 -o /media/backup/full/$(date +%Y%m%d)

三、 原单节点MongoDB配置信息

角色IP
单节点IP:10.10.10.45 端口:27017

该节点配置信息:

# cat /etc/mongod.conf |grep -v '^#'


systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  #bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
  bindIp: 0.0.0.0

修改该配置文件增加副本集配置

# cat /etc/mongod.conf |grep -v '^#'


systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  #bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
  bindIp: 0.0.0.0


replication:
  oplogSizeMB: 4096
  replSetName: rs

四、新增节点信息

角色IP
新增从节点IP:10.10.10.46 端口:27017
新增仲裁节点IP:10.10.10.47 端口:27017

这两个节点配置文件,只需复制PRIMARY节点配置文件,并修改相应的 "bindIp"即可。
从节点配置:

# cat /etc/mongod.conf |grep -v '^#'


systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  #bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
  bindIp: 0.0.0.0


replication:
  oplogSizeMB: 4096
  replSetName: rs

仲裁节点配置:

# cat /etc/mongod.conf |grep -v '^#'


systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true

processManagement:
  timeZoneInfo: /usr/share/zoneinfo

net:
  port: 27017
  #bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
  bindIp: 0.0.0.0




replication:
  oplogSizeMB: 4096
  replSetName: rs

启动3个节点:要先启动PRIMARY节点,2个SECONDARY节点后面启动。

# systemctl start mongod

五、 初始化副本集

使用mongo shell连接到主节点,执行初始化命令

test> use admin
switched to db admin
admin> 
config = {
  _id : "rs", 
  members : [
    {_id:0, host:"10.10.10.45:27017"},
    {_id:1, host:"10.10.10.46:27017"},
    {_id:2, host:"10.10.10.47:27017", arbiterOnly: true},
  ]
}

> rs.initiate(config)               //初始化副本集
{ ok: 1 }                          //返回ok:1成功,返回ok:0失败

在这里插入图片描述

• 查看集群状态信息

rs [direct: secondary] admin> rs.status()
{
  set: 'rs',
  date: ISODate('2024-07-06T08:56:17.985Z'),
  myState: 1,
  term: Long('1'),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long('2000'),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 2,
  optimes: {
    lastCommittedOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
    lastCommittedWallTime: ISODate('2024-07-06T08:56:09.745Z'),
    readConcernMajorityOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
    appliedOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
    durableOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
    lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),
    lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z')
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1720256159, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate('2024-07-06T08:54:19.727Z'),
    electionTerm: Long('1'),
    lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1720256048, i: 1 }), t: Long('-1') },
    lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1720256048, i: 1 }), t: Long('-1') },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long('10000'),
    numCatchUpOps: Long('0'),
    newTermStartDate: ISODate('2024-07-06T08:54:19.734Z'),
    wMajorityWriteAvailabilityDate: ISODate('2024-07-06T08:54:20.619Z')
  },
  members: [
    {
      _id: 0,
      name: '10.10.10.45:27017',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 449,
      optime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
      optimeDate: ISODate('2024-07-06T08:56:09.000Z'),
      lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),
      lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z'),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1720256059, i: 1 }),
      electionDate: ISODate('2024-07-06T08:54:19.000Z'),
      configVersion: 1,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: '10.10.10.46:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 129,
      optime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
      optimeDurable: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },
      optimeDate: ISODate('2024-07-06T08:56:09.000Z'),
      optimeDurableDate: ISODate('2024-07-06T08:56:09.000Z'),
      lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),
      lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z'),
      lastHeartbeat: ISODate('2024-07-06T08:56:17.775Z'),
      lastHeartbeatRecv: ISODate('2024-07-06T08:56:16.777Z'),
      pingMs: Long('0'),
      lastHeartbeatMessage: '',
      syncSourceHost: '10.10.10.45:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    },
    {
      _id: 2,
      name: '10.10.10.47:27017',
      health: 1,
      state: 7,
      stateStr: 'ARBITER',
      uptime: 129,
      lastHeartbeat: ISODate('2024-07-06T08:56:17.776Z'),
      lastHeartbeatRecv: ISODate('2024-07-06T08:56:17.775Z'),
      pingMs: Long('0'),
      lastHeartbeatMessage: '',
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1720256169, i: 1 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1720256169, i: 1 })
}

查看从库延时信息

rs [direct: primary] admin> rs.printSecondaryReplicationInfo()
source: 10.10.10.46:27017
{
  syncedTo: 'Sat Jul 06 2024 16:57:29 GMT+0800 (China Standard Time)',
  replLag: '0 secs (0 hrs) behind the primary '
}

上面看到从库已经完全同步,没有延时。

六、测试数据

–主库插入数据

rs [direct: primary] admin> for(i=0;i<1000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6})};
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
  acknowledged: true,
  insertedIds: { '0': ObjectId('6689087d597863336614a32f') }
}
rs [direct: primary] admin> show tables;
log
mycollection
system.keys
system.users
system.version

–从库上查看数据

rs [direct: secondary] admin> show tables;
log
mycollection
system.keys
system.users
system.version
rs [direct: secondary] admin> db.log.find().count()
1000

由此可以看出,主从节点数据同步正常。

关注我,学习更多数据库知识。
请添加图片描述

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

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

相关文章

沪上繁花:上海电信的5G-A之跃

2024年6月18日下午&#xff0c;在上海举行的3GPP RAN第104次会议上&#xff0c;3GPP正式宣布R18标准冻结。R18是无线网络面向5G-A的第一个版本&#xff0c;其成功冻结正式宣布了5G发展迎来新机遇&#xff0c;5G-A商用已进入全新的发展阶段。 在5G-A滚滚而来的时代洪流中&#x…

【88 backtrader期货策略】一个基于螺纹钢和铁矿5分钟K线数据的跨品种日内套利策略回测

这是参考其他量化框架的跨品种套利策略并进行修改逻辑后实现的一个交易策略。花了小半天时间,核对了策略逻辑的细节,两者的资金曲线基本是可以对齐了。 提醒 这个统计套利策略回测的时候,有几个坑,会导致实盘和回测的结果出现比较大的差异。在后续文章中,我将分析为什么…

【3D->2D转换(1)】LSS(提升,投放,捕捉)

Lift, Splat, Shoot 这是一个端到端架构&#xff0c;直接从任意数量的摄像头数据提取给定图像场景的鸟瞰图表示。将每个图像分别“提升&#xff08;lift&#xff09;”到每个摄像头的视锥&#xff08;frustum&#xff09;&#xff0c;然后将所有视锥“投放&#xff08;splat&a…

Spring相关面试题(四)

49 JavaConfig方式如何启用AOP?如何强制使用cglib&#xff1f; 在JavaConfig类&#xff0c;加上EnableAspectJAutoProxy 如果要强制使用CGLIB动态代理 &#xff0c;加上(proxyTargetClass true) 加上(exposeProxy true) 就是将对象暴露到线程池中。 50 介绍AOP在Spring中…

word文档没有保存就关闭了怎么恢复?找到正确的方法

昨天写教程的时候&#xff0c;终于完成了一个word文档&#xff0c;以为保存了就直接关了。word提醒我“是否保存”&#xff0c;我直接忽略了。动作一气呵成&#xff0c;毫不犹豫的关闭了。之后才发现我没有保存word文档。这种情况大家有遇到过吗?我们该如何在没有保存的情况下…

unix高级编程系列之文件I/O

背景 作为linux 开发者&#xff0c;我们不可避免会接触到文件编程。比如通过文件记录程序配置参数&#xff0c;通过字符设备与外设进行通信。因此作为合格的linux开发者&#xff0c;一定要熟练掌握文件编程。在文件编程中&#xff0c;我们一般会有两类接口函数&#xff1a;标准…

原生JavaScript实现录屏功能

1. 前言 使用JavaScript实现浏览器中打开系统录屏功能 示例图: 2. 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><…

关于CPU你一定要注意的重要参数,警惕韭菜陷阱

昨天遇到个奇葩事&#xff0c;有个粉丝喷我“懂不懂什么叫I9&#xff1f;”言下之意就是CPU中I9>i7>I5>I3&#xff0c;我也不知道咋说&#xff0c;只是提醒大家小心被坑&#xff0c;花了多的钱用的差的性能。作为回应&#xff0c;仅以此篇说下CPU咱们臭打游戏一定要知…

软件架构之计算机组成与体系结构

1.1计算机系统组成 计算机系统是一个硬件和软件的综合体&#xff0c;可以把它看成按功能划分的多级层次结构。 1.1.1 计算机硬件的组成 硬件通常是指一切看得见&#xff0c;摸得到的设备实体。原始的冯•诺依曼&#xff08;VonNeumann&#xff09;计算机在结构上是以运算器为…

基于Android Studio点餐项目,点餐app

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 实现登录、注册、注销功能&#xff0c;退出登录等功能&#xff0c; 以及基本的选择店铺点餐&#xff0c;加入购物车和结算等功能&#xff0c;以及可以增加或者减少商品的个数&#xff0c; 同时可以同步价格的总量。以…

智能化客户服务:提升效率与体验的新模式

在数字化浪潮的推动下&#xff0c;客户服务领域正经历着一场深刻的变革。智能化客户服务的兴起&#xff0c;不仅重塑了企业与客户之间的互动方式&#xff0c;更在提升服务效率与增强客户体验方面展现出了巨大潜力。本文将深入探讨智能化客户服务的新模式&#xff0c;分析其如何…

【C语言】自定义类型:联合和枚举

前言 前面我们学习了一种自定义类型&#xff0c;结构体&#xff0c;现在我们学习另外两种自定义类型&#xff0c;联合 和 枚举。 目录 一、联合体 1. 联合体类型的声明 2. 联合体的特点 3. 相同成员联合体和结构体对比 4. 联合体大小的计算 5. 用联合体判断当前机…

single_test_funi.py: error: the following arguments are required: img

parser.add_argument(img, defaultS/1.jpg, helpImage file) 当你已经指定了文件路径&#xff0c;还是报错怎么办&#xff1f; parser.add_argument(img, nargs?, defaultS/1.jpg, helpImage file) nargs? 表示 config 参数是可选的。如果用户没有提供这个参数&#xff0c…

25款404网页源码(下)

25款404网页源码&#xff08;下&#xff09; 13部分源码 14部分源码 15部分源码 16部分源码 17部分源码 18部分源码 19部分源码 20部分源码 21部分源码 22部分源码 23部分源码 24部分源码 25部分源码 领取完整源码下期更新 13 部分源码 .rail {position: absolute;width: 100%…

关注推送---Feed流,推模式实现的个人分析及其思考。

本篇文章记录我们实际开发过程中&#xff0c;关注推送场景的个人思考&#xff0c;以及解析。 文章目录 前言一、关注推送是什么&#xff1f;是什么是Feed流&#xff1f;二、解决关注推送问题的技术方案1.理论模型的选取2.数据类型的选取 三、理论模型的选取三、数据类型的选取总…

7寸微型FPV无人机技术详解

对于7寸微型FPV&#xff08;First Person View&#xff0c;第一人称视角&#xff09;无人机技术的详解&#xff0c;可以从以下几个方面进行介绍&#xff1a; 一、定义与基本概念 FPV无人机&#xff0c;全称为“第一人称视角无人机”&#xff0c;它利用安装在无人机上的摄像头…

QT c++函数模板与类模板的使用

QT c类模板的使用 #pragma once#include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication5.h"class QtWidgetsApplication5 : public QMainWindow {Q_OBJECTpublic:QtWidgetsApplication5(QWidget *parent nullptr);~QtWidgetsApplication5();te…

HTML5使用<mark>标签:高亮显示文本

1、<mark>标签的使用 mark 标签用于表示页面中需要突出显示或高亮的一段文本&#xff0c;这段文本对于当前用户具有参考作用。它通常在引用原文以引起读者注意时使用。<mark>标签的作用相当于使用一支荧光笔在打印的纸张上标出一些文字。它与强调不同&#xff0c;…

Go语言--复合类型之指针与数组

分类 指针 指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。Go 语言对指针的支持介于 Java 语言和 C/C语言之间,它既没有想 Java 语言那样取消了代码对指针的直接操作的能力,也避免了 C/C语言中由于对指针的滥用而造成的安全和…