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
# 主节点配置
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表示不使用子进程守护)

将对应的文件夹、文件构建出来:
mkdir -p /data/mongo/data/server1
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server1.log
启动服务:
./mongod -f mongo_37017.conf
顺利启动:

从节点1配置
mongo_37018.conf
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表示不使用子进程守护)

将对应的文件夹、文件构建出来:
mkdir -p /data/mongo/data/server2
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server2.log
启动服务:
./mongod -f mongo_37018.conf
这次的启动我是 fork:true,可以对比一下有什么不同:

从节点2配置
mongo_37019.conf
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表示不使用子进程守护)

将对应的文件夹、文件构建出来:
mkdir -p /data/mongo/data/server3
mkdir -p /data/mongo/logs
touch /data/mongo/logs/server3.log
启动服务:
./mongod -f mongo_37019.conf

初始节点配置
启动三个节点,然后进入任意一个节点执行,我的节点是:10.10.52.38
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()


节点增删
手动增加节点:
rs.add("ip:37019")
也可以删除节点:
rs.remove("ip:37019")
复制操作
进入主节点-插入数据-检查从节点
PS:默认状态下从节点是不可以读取数据的,需要调用 rs.slaveOk() 才可以。
为了保证高可用,在集群当中如果主节点挂掉后,会自动在从节点中选举一个作为主节点。我们可以用 rs.status()
● PRIMARY:可以查询和新增数据
● SECONDARY:只能查询,不能新增,基于Priority权重可以选为主节点
● ARBITER:不能查询数据和新增数据,不能成为主节点
配置参数

举例:
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 或启用路由 |
回滚剧本
临时让当前主让位(维护场景):
rs.stepDown(60) // 60 秒内不再当主
变更成员/优先级(原子方式):
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案例 详解
🔗 大数据模块直达链接
