跨服务器MongoDB集群700GB级大数据迁移方案咨询
直接给结论:你最初设想的跨集群直接加副本节点的方案完全不可行
别直接把存有存量数据的目标端服务器B加到源集群副本集,MongoDB副本集的初始同步逻辑默认会把新加入节点本地的数据目录整个清空,从源Primary拉全量数据重建,根本不会保留B上的原有旧数据,700G量级下不仅会丢目标端存量数据,同步打满源端带宽、IO还会直接影响源集群正常业务。
就算你硬改配置跳过初始同步校验,只要两套集群存在_id重叠的旧数据,副本同步时会直接触发唯一键冲突报错,同步进程中断,根本达不到合并增量的目的。
700G数据量下经过生产验证的可行方案
比你之前测的mongodump/mongoimport、Compass导入导出快3-6倍,不会出现进程崩溃问题,数据一致性有保障,根据你的业务停机容忍度二选一就行:
方案1:零停机迁移,优先选(稳定性最高)
全程不影响源集群、目标集群的正常业务读写,操作顺序如下:
- 先给两套集群各做一次本地磁盘快照备份,重点备份目标端存量数据,备份完做抽样校验,防止操作失误丢数。
- 不要动现有4台生产服务器的配置,单独准备一台同配置的临时备机,磁盘预留1.5倍数据量的冗余空间,部署和源集群同大版本的MongoDB实例,以无投票权的隐藏副本节点身份加入源集群。配置同步时的IO、带宽上限,避免打满源集群资源,等全量初始同步完成、oplog延迟稳定在1s以内就算这步完成,万兆内网环境下700G数据大概4-6小时能跑完。
- 临时备机追平源端数据后,将其从源集群副本集移除,以单实例模式启动。逐库逐集合用MongoDB自带的
$merge聚合阶段,把临时备机上的源数据合并到目标集群的服务器B:合并规则设为按_id匹配,目标端已存在的文档直接跳过,只插入源端存在、目标端不存在的新增数据。这个操作是MongoDB进程内执行的,不需要把数据导出到磁盘,速度远快于逻辑导入导出;大集合可以按_id哈希拆成16-32个分片并发执行,打开allowDiskUse: true参数避免内存不足报错,700G数据大概2-3小时就能合并完成。 - 合并完成后做全量校验:每个集合对比两端文档数、索引数量、索引大小,随机抽取1%-2%的文档对比字段哈希值,确认所有新增数据都完整写入B、没有覆盖目标端原有旧数据。
- 校验通过后,把目标集群原有第二台服务器C配置为B的副本节点,加入目标集群副本集,等B到C的初始同步完成、oplog追平后,调整副本集节点优先级、投票权到正常配置,迁移完成。
方案2:允许15分钟以内停机窗口,选这个(操作步骤最少,速度最快)
如果业务可以接受短时间停写,流程更简单:
- 先调大源集群的oplog大小,确保oplog窗口能覆盖至少24小时的写入量,避免同步过程中oplog被覆盖导致断流,记录当前源集群的oplog时间戳T1。
- 直接对源集群的数据目录做物理快照,通过rsync等块拷贝方式直接同步到服务器B的临时数据目录,物理拷贝的速度远快于逻辑导出,700G数据大概2-3小时就能传完,这期间源集群可以正常读写。
- 物理拷贝完成后,在B上启动临时单实例,持续重放源集群T1时间点之后的oplog,追到和源集群的延迟小于1s。
- 给业务发停写通知,等B上的oplog重放完全追平源集群停写的时间点,两边数据校验一致后,直接把业务读写切到目标集群,恢复业务写入。最后把C节点加入B的副本集,完成冗余配置即可。
几个必须避开的坑
- 绝对不要直接把存有数据的节点跨集群加入副本集,100%触发初始同步清空本地数据,生产环境这么操作大概率出重大故障。
- 不要不加参数直接跑
mongodump/mongorestore导700G数据,默认逻辑导出会把数据序列化后加载到内存,数据量超过可用内存阈值就会OOM崩溃,就算调大内存参数,序列化/反序列化的开销也比物理同步、进程内合并高一个数量级。 - 不要等全流程跑完才做校验,每完成一个集合的同步就做一次计数、索引、抽样数据校验,早发现问题早回滚。
- 所有操作先在测试环境用同量级模拟数据跑通全流程,算准每个步骤的耗时、资源占用阈值,再上生产操作。
内容的提问来源于stack exchange,提问作者AcidBurn
相关产品推荐
相关产品推荐

