Java-160 MongoDB副本集部署实战 单机三实例/多机同法 10 分钟起集群 + 选举/读写/回滚全流程

TL;DR

  • 场景:在一台机器上快速搭 3 实例副本集,理解 PRIMARY/SECONDARY/多数派。
  • 结论:按本文 SOP,10 分钟可跑通;附"读从/回滚/扩容/常见报错"速查卡。
  • 产出:三份可直接用的 YAML 配置、初始化脚本、rs.reconfig

版本矩阵

组件 已验证 备注
MongoDB 7.x / 8.0 mongod, mongosh
OS Linux x86_64 本机三实例,端口 37017/37018/37019

集群搭建2-多机版

这里为了方便进行测试,我们将会在一台主机上进行三个节点的搭建,当然如果你有三台主机的话,搭建方式也是一样的。

主节点配置

mongo_37017.conf

shell 复制代码
# 主节点配置
dbpath=/data/mongo/data/server1
bind_ip=0.0.0.0
port=37017
fork=true
logpath=/data/mongo/logs/server1.log
replSet=WzkCluster

PS: fork 参数可以选择 false 或者 删除(表示是否启动一个子进程来守护运行,如果只是学习测试,false表示不使用子进程守护)

将对应的文件夹、文件构建出来:

shell 复制代码
mkdir -p /data/mongo/data/server1
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server1.log

启动服务:

shell 复制代码
./mongod -f mongo_37017.conf 

顺利启动:

从节点1配置

mongo_37018.conf

shell 复制代码
dbpath=/data/mongo/data/server2
bind_ip=0.0.0.0
port=37018
fork=true
logpath=/data/mongo/logs/server2.log
replSet=WzkCluster

PS: fork 参数可以选择 false 或者 删除(表示是否启动一个子进程来守护运行,如果只是学习测试,false表示不使用子进程守护)

将对应的文件夹、文件构建出来:

shell 复制代码
mkdir -p /data/mongo/data/server2
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server2.log

启动服务:

shell 复制代码
./mongod -f mongo_37018.conf 

这次的启动我是 fork:true,可以对比一下有什么不同:

从节点2配置

mongo_37019.conf

shell 复制代码
dbpath=/data/mongo/data/server3
bind_ip=0.0.0.0
port=37019
fork=true
logpath=/data/mongo/logs/server3.log
replSet=WzkCluster

PS: fork 参数可以选择 false 或者 删除(表示是否启动一个子进程来守护运行,如果只是学习测试,false表示不使用子进程守护)

将对应的文件夹、文件构建出来:

shell 复制代码
mkdir -p /data/mongo/data/server3
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server3.log

启动服务:

shell 复制代码
./mongod -f mongo_37019.conf 

初始节点配置

启动三个节点,然后进入任意一个节点执行,我的节点是:10.10.52.38

shell 复制代码
var cfg ={
  "_id":"WzkCluster",
  "protocolVersion" : 1,
  "members":[
    {"_id":1,"host":"10.10.52.38:37017","priority":10},
    {"_id":2,"host":"10.10.52.38:37018"}
  ]
}
rs.initiate(cfg)
rs.status()

节点增删

手动增加节点:

shell 复制代码
rs.add("ip:37019")

也可以删除节点:

shell 复制代码
rs.remove("ip:37019")

复制操作

进入主节点-插入数据-检查从节点

PS:默认状态下从节点是不可以读取数据的,需要调用 rs.slaveOk() 才可以。

为了保证高可用,在集群当中如果主节点挂掉后,会自动在从节点中选举一个作为主节点。我们可以用 rs.status()

● PRIMARY:可以查询和新增数据

● SECONDARY:只能查询,不能新增,基于Priority权重可以选为主节点

● ARBITER:不能查询数据和新增数据,不能成为主节点

配置参数

举例:

shell 复制代码
var cfg ={
  "_id":"WzkCluster",
  "protocolVersion" : 1,
  "members":[
    {"_id":1,"host":"10.10.52.38:37017","priority":10},
    {"_id":2,"host":"10.10.52.383:37018","priority":0},
    {"_id":3,"host":"10.10.52.38:37019","priority":5}
  ]
};
// 重新装载配置 并重新生成集群节点
rs.reconfig(cfg)
//重新查看集群状态
rs.status()

仲裁节点复制

和上面的配置步骤相同,只是增加了一个特殊的仲裁节点

注入节点执行 rs.addArb("IP:端口")

错误速查

症状/报错 可能根因 定位命令/字段 修复动作
节点不加入 replSetName 不一致 rs.status().members.stateStr 统一为 WzkCluster,重启节点
选主反复/不可写 少于多数票 rs.status().term 连续变化 立刻补齐第 3 节点或降为单节点测试
连接从库读失败 读偏好未设置 驱动日志/URI URI 加 readPreference=secondaryPreferred
ECONNREFUSED IP/端口/拼写错 netstat -tnlp 修正 IP(避免写成 ...52.383 这种)
not master/not primary 写到了从库 客户端异常栈 切换到 PRIMARY 或启用路由

回滚剧本

临时让当前主让位(维护场景):

shell 复制代码
rs.stepDown(60)   // 60 秒内不再当主

变更成员/优先级(原子方式):

shell 复制代码
cfg = rs.conf()
cfg.members[2].priority = 0    // 让第3个节点永不当主
rs.reconfig(cfg, { force: false })

其他系列

🚀 AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究 ,持续打造实用AI工具指南!
AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈
🔗 AI模块直达链接

💻 Java篇持续更新中(长期更新)

Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例

MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
🔗 大数据模块直达链接

相关推荐
梦未3 分钟前
Spring控制反转与依赖注入
java·后端·spring
喜欢流萤吖~4 分钟前
Lambda 表达式
java
Dragon online10 分钟前
数据分析师成长之路--从SQL恐惧到数据掌控者的蜕变
数据库·sql
ZouZou老师21 分钟前
C++设计模式之适配器模式:以家具生产为例
java·设计模式·适配器模式
曼巴UE544 分钟前
UE5 C++ 动态多播
java·开发语言
VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue音乐管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
一招定胜负1 小时前
navicat连接数据库&mysql常见语句及操作
数据库·mysql
程序员鱼皮1 小时前
刚刚,IDEA 免费版发布!终于不用破解了
java·程序员·jetbrains
热心市民蟹不肉1 小时前
黑盒漏洞扫描(三)
数据库·redis·安全·缓存