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 小时前
使用 Actix-web 开发高性能 Web 服务
前端·数据库
sinat_286945194 小时前
Java事故排查
java·开发语言
Pluchon4 小时前
硅基计划2.0 学习总结 玖 图书管理系统 2.0复盘版(文字末尾源码可复制)
java·学习·项目·源码可复制
摇滚侠4 小时前
Spring Boot3零基础教程,事件驱动开发,设计登录成功后增加积分记录信息功能,笔记61
java·spring boot·笔记·后端
与衫4 小时前
SQL 调试不再靠猜:Gudu SQL Omni 让血缘分析一键可视化
数据库·sql
凯子坚持 c4 小时前
Docker LXC深度解析:从基础概念到实战演练
java·开发语言
m0_748233644 小时前
【C++篇】C++11入门:踏入C++新世界的大门
java·c++·算法
ZZZKKKRTSAE4 小时前
MySQL一篇速通
数据库·mysql·1024程序员节
阿祥~4 小时前
windows 安装 Redis
数据库·redis·缓存