将运行一段时间的单机MongoDB平滑迁移至副本集集群,核心是避免业务中断,需分阶段规划部署、数据同步及连接切换。以下是详细实施步骤:
一、前期准备:规划与环境适配
1. 副本集架构设计
副本集需满足“多数节点可用”(用于选举主节点),推荐3节点架构(生产环境最常用):
- 1个主节点(Primary):处理所有写操作,同步数据到从节点;
- 1个从节点(Secondary):复制主节点数据,可分担读压力;
- 1个仲裁节点(Arbiter):不存储数据,仅参与选举(降低硬件成本)。
若数据量较大或需更高可用性,可替换为3个数据节点(无仲裁),但需更多硬件资源。
2. 环境与版本检查
- 版本一致性:新节点MongoDB版本必须与原单机实例完全一致(避免数据同步兼容问题);
- 网络互通:原节点与新节点需开放27017端口(MongoDB默认端口),确保双向通信(可通过
telnet 节点IP 27017
验证); - 权限配置:若原实例启用了认证(
--auth
),需提前准备密钥文件(keyFile)(用于副本集内部认证),所有节点密钥文件内容必须相同。
二、部署新节点:避免业务影响
1. 部署从节点与仲裁节点
- 安装MongoDB:在新服务器上安装与原实例同版本的MongoDB,配置数据目录(如
/data/mongodb
)、日志目录(如/var/log/mongodb
); - 配置文件示例(以从节点为例,仲裁节点配置类似,仅需添加
arbiterOnly: true
):systemLog: destination: file path: /var/log/mongodb/node2.log storage: dbPath: /data/mongodb/node2 journal: enabled: true net: port: 27017 bindIp: 0.0.0.0 # 允许其他节点访问 replication: replSetName: "rs_prod" # 副本集名称(需与原节点一致) security: authorization: enabled # 若原实例有认证,需开启 keyFile: /etc/mongodb/keyfile # 密钥文件路径(权限需设为600)
- 启动新节点:通过配置文件启动(
mongod -f 配置文件路径
),确保进程正常运行(ps -ef | grep mongod
)。
三、单机实例转换为副本集:最小化业务中断
原单机实例需转换为副本集的第一个节点(初始主节点),此过程需短暂重启,需控制在业务低峰期操作。
1. 备份数据(关键!)
- 用
mongodump
做全量备份(避免操作失误导致数据丢失):mongodump --host 原节点IP --port 27017 --out /backup/mongodb_$(date +%F)
2. 原实例启用副本集模式
- 修改配置文件:在原实例配置中添加副本集名称:
replication: replSetName: "rs_prod" # 与新节点一致
- 重启原实例:快速重启(中断时间通常<30秒),重启命令:
此时原实例以“单节点副本集”模式运行,业务暂时仍可连接(读写正常)。# 先停止原实例 mongod --shutdown --dbpath /原数据目录 # 用新配置启动 mongod -f 原配置文件路径
3. 初始化副本集
- 连接原实例(
mongo 原节点IP:27017
),执行初始化命令:rs.initiate({ _id: "rs_prod", members: [ { _id: 0, host: "原节点IP:27017" } // 原实例作为第一个成员 ] })
- 验证状态:
rs.status()
应显示原节点为PRIMARY
。
四、添加新节点至副本集:在线同步数据
新节点加入后会自动从主节点(原实例)同步数据(初始同步),此过程不影响主节点处理业务。
1. 添加从节点
- 在主节点(原实例)的Mongo Shell中执行:
rs.add({ _id: 1, host: "从节点IP:27017" // 新部署的从节点 })
- 查看同步状态:
rs.status()
中从节点的stateStr
会经历STARTUP
→STARTUP2
→RECOVERING
→SECONDARY
(同步完成)。
2. 添加仲裁节点(可选)
- 若架构包含仲裁节点,继续执行:
rs.addArb("仲裁节点IP:27017") // 仲裁节点无需存储数据
五、业务连接切换:平滑过渡至副本集
业务需从“连接单机实例”改为“连接副本集”,确保驱动自动发现主节点并容错。
1. 连接字符串修改
原连接字符串(单机):
mongodb://原节点IP:27017/dbname
新连接字符串(副本集):
mongodb://原节点IP:27017,从节点IP:27017,仲裁节点IP:27017/dbname?replicaSet=rs_prod
- 关键参数:
replicaSet=rs_prod
必须指定,驱动会通过此参数识别副本集; - 读偏好设置(可选):若需读写分离,添加
readPreference=secondaryPreferred
(优先从从节点读)。
2. 灰度切换业务
- 先在部分非核心业务实例中更新连接字符串,验证读写正常(写操作自动路由到主节点,读操作按配置路由);
- 确认无误后,批量更新所有业务实例,完成切换。
六、验证与监控:确保集群稳定
1. 功能验证
- 检查数据一致性:在主节点写入数据,验证从节点是否同步(
db.collection.find()
对比); - 故障转移测试:手动停止主节点(
mongod --shutdown
),观察副本集是否自动选举从节点为新主节点(约10-30秒),业务是否自动切换连接。
2. 监控指标
- 同步延迟:
rs.printSlaveReplicationInfo()
查看从节点与主节点的延迟(应<1秒); - 节点状态:通过MongoDB Compass或
rs.status()
监控各节点状态; - 性能指标:关注主节点CPU、内存、IO(避免同步影响业务)。
关键注意事项
- 初始同步优化:若数据量过大(>100GB),直接通过网络同步耗时久,可先停主节点(短暂),复制数据文件到从节点(
cp -r /原数据目录/* /从节点数据目录/
),再启动从节点(仅同步增量数据); - 驱动兼容性:确保业务使用的MongoDB驱动版本支持副本集(如Python的pymongo≥3.0,Java的mongo-java-driver≥3.0);
- 认证配置:若原实例有认证,所有节点必须使用相同的密钥文件,否则副本集内部通信失败;
- 业务低峰操作:原实例重启、故障转移测试等步骤需在业务低峰期执行,降低影响。
通过以上步骤,可实现单机MongoDB到副本集的平滑迁移,全程业务中断时间可控制在分钟级(主要为原实例重启),且数据零丢失。