MONGODB 数据库在很多应用场景中都有需要进行数据同步的方案需求
1 多数据中心数据同步方案
2 数据灾备方案
3 多点数据写入与数据最终一致性方案
这些方案中不可或缺的就是mongoshake 组件,mongoshake是阿里云NOSQL团队TEAM 开发的一款针对与通用性服务平台的产品,通过对mongodb的oplog进行读取将源于目的的MOGNODB 数据库之间进行数据同步的方式。通过日志的抓取和重放的方式完成数据同步的任务,数据同步中通过通道来进行数据传输,其中包含了像rpc, file, tcp,以及直连等方式。通过选择不同的同步方式,可以对接不同的中间件,如kafka,通过发布和订阅的方式来进行数据的异步的灵活同步。
基于数据同步,源端可以是单体的MONGODB ,也可以是复制集合,也可以是分片集合,在使用集合的状态下,可以通过在从库中获取OPLOG的方式,降低与主库的FETCH操作带来的对主库的性能影响。
基于MONGOSHAKE, 主要提供了如下的几种特性
1 parallel replication 并行的复制,主要通过唯一索引的方式对 collections的数据进行并行复制,或者对database collection 进行并行。
2 支持断点续传的功能,主要是在进行数据的FETCH 的情况下会将数据同步的点写入到源数据库中,在源数据库中建立了MONGOSHAKE的数据库,建立相关的表来记录信息。
下方的就是在源端存储信息的表
3 可以通过配置白名单和黑名单的方式将某些数据库或collection 集合排除或加入到复制的列表中
4 DDL 操作同步,目前的最新版本的mongoshake是 2.6.6 版本,从1.5版本的mongoshake 就开始支持了DDL 操作,但这里有一个问题,在操作DDL 后,数据同步还是持续的,会造成一个问题,目的端的DDL 操作还未完成,但是主库这边做完后,数据就推过来了,造成数据复制出错,或停止,mongoshake 通过添加了 闩的方式,要求只有目的端的DDL 操作结束后,基于这些DDL 操作后面的数据才能发送到目的端。
5 双向MONGODB 同步(仅仅阿里云MONGODB RDS 支持,DTS),在同步的数据库中标识复制的数据库的ID,通过这样的方式避免双向同步的产生重复读取数据的问题(还回数据)
6 支持数据的压缩,和重定向功能,如将传输的数据直接定位到文件中。
那么在了解了上面的信息后,实际上MONGOSHAKE 在开源的环境中,产生单向的复制是有效的。
下面基于MONGOSHAKE 的数据同步,进行一个相关MOGNODB 升级中不进行长时间的业务短接的方案。
3台虚拟机,
1 安装mongodb 3.4.24
2 安装mongodb 4.2
3 安装mongoshake 2.6.6
2台测试机需要注意,是单机,但需要打开oplogs 所以在生成单机的步骤后,需要对数据库进行 rs.initiate() 将单体的MONGODB 变成 primary 的复制集的方式。
在另一台mongoshake 的机器上将下载的二进制的压缩包进行解压,
https://github.com/alibaba/MongoShake/releases/tag/release-v2.6.6-20220323
基本参数
conf.version = 10 #配置文件版本号不要修改
id = mongoshake #id 用于输出pid文件
master_quorum = false #当一个
full_sync.http_port = 9101 #全量和增量监控窗口
incr_sync.http_port = 9100 #全量和增量监控窗口
system_profile_port = 9200 #查看mongoshake 内部性能
log.level = info #日志的等级
log.dir = /home/mongo #日志存放地
log.file = collector.log #日志文件名
log.flush = true #日志是否是实时刷新的
sync_mode = all #如果是全量 增量同步数据需要选择all 如果是仅仅迁移全量数据使用 full #如果是使用增量同步使用incr 这里需要之前有过复制信息,否则无法进行新的增量同步。
tunnel = direct #通道模式,进行数据同步
tunnel.message = raw #数据输出的方式
mongo_connect_mode = secondaryPreferred #数据的读取为secondary perfer
filter.namespace.black = #黑白名单,通过db, db.collection 提出数据库库或collection
filter.namespace.white =
filter.ddl_enable = false #传输数据是隔离DDL 操作
checkpoint.storage.db = mongoshake #存储在源端的数据库
checkpoint.storage.collection = ckpt_default #存储在源端的表名,多个mongoshake 需要避免同一个表名
checkpoint.start_position = 1970-01-01T00:00:00Z #如果checkpoint不存在,并且值为 1970-01-01T00:00:00Z, 则开始拉取所有的OPLOG ,如果发现OPLOG 时间点比1970-01-01T00:00:00Z 还要早,则直接停止复制
full_sync.reader.collection_parallel = 6 #全量拉取数据时,一次性拉取数据表的数量
full_sync.reader.write_document_parallel = 8 #针对一个表最大能并发多少线程进行数据的拉取
full_sync.reader.document_batch_size = 128 #一次发给目的端多少行数据
full_sync.collection_exist_drop = true #数据库同步时发现目的方有库,直接删除数据库,false 停止复制
full_sync.create_index = background #在数据同步完毕后在后台创建索引
full_sync.executor.insert_on_dup_update = false #发生主键冲突后,直接将insert语句改为UPDATE
incr_sync.mongo_fetch_method = oplog #增量拉取数据的方法
数据库源端信息
mongo_urls = mongodb://admin:1234.Com@192.168.198.100:27027
数据库目的信息
tunnel.address = mongodb://admin:1234.Com@192.168.198.101:27027
配置文件这边已经做好直接在MONGOSHAKE环节启动
collector.linux -conf=/usr/local/mongoshake/collector.conf -verbose 0
启动后数据开始全部同步,这里在源库上添加索引,由于两边的数据库版本不同,导致出现报错信息,参见图2
其中主要的原因是,MONGODB 3.4 中的之前的 system.indexes 在mongodb 4.2 已经清除了,导致创建索引在 mongodb 4.2 上DDL 命令操作失败。