如何基于本地离线Mongo副本差异更新线上Mongo数据库,避免全量上传
MongoDB 增量同步实现方案
MongoDB 本身自带原生的变更追踪能力,完全可以实现仅传差异的增量同步,无需每次全量上传数GB数据。
方案一:基于原生oplog的同步(最稳定推荐)
oplog是MongoDB副本集架构中用于记录所有数据变更操作的日志,仅存储写入、更新、删除类操作的元数据和变更内容,体积远小于全量数据,完全可以类比为Git的commit记录。
操作步骤如下:
- 本地MongoDB配置单节点副本集开启oplog:修改mongod配置文件新增如下配置
重启MongoDB后进入shell执行replication: replSetName: "rs0" oplogSizeMB: 10240 # 按自己的变更量调整,建议至少保留7天以上的操作日志rs.initiate()完成副本集初始化。 - 首次基准同步:用
mongodump导出本地全量数据,传输到线上后用mongorestore导入,同时记录下当前oplog的最新时间戳作为后续增量同步的起始点位。 - 后续定期增量同步:每次同步时仅导出本地oplog中晚于上一次记录的时间戳的所有操作记录,传输到线上后直接重放这些操作即可,每次传输量仅为两次同步间隔内的变更数据,通常为KB到MB级别。
- 可以写定时脚本自动完成上述全流程,线上业务无感知。
方案二:自定义变更标记同步(无需调整本地Mongo架构)
如果不想修改本地MongoDB的副本集配置,可以自己实现轻量变更追踪:
- 给所有文档新增
update_at时间戳字段,离线应用每次编辑文档时自动更新该字段为当前时间。 - 单独维护一张
del_records集合,记录所有被删除文档的_id和删除时间,每次删除操作执行时同步写入该集合。 - 每次同步时,先导出本地库中
update_at大于上一次同步时间的所有文档,以及del_records中晚于上一次同步时间的删除记录,传输到线上后分别执行upsert和删除操作即可,同步完成后清空del_records中已同步的记录。
注意事项
- 同步前建议先在线上临时环境重放变更校验正确性,避免错误操作影响线上业务。
- 若使用oplog方案,要根据你的同步频率调整oplog的保留时长,避免两次同步间隔过长导致oplog被覆盖,需要重新做全量同步。
- 同步传输时可开启gzip压缩,进一步降低传输体积。
内容的提问来源于stack exchange,提问作者Inkbug
相关产品推荐
相关产品推荐

