MongoShake:数据迁移之王,MongoDB领域的绝对霸主,让数据轻松穿梭无边界!

b9a223353ebef6c3a9529c9df3a817a8.jpeg

简介

     MongoShake 是一个用于 MongoDB 数据库的数据复制工具,它可以实现 MongoDB 数据库之间的数据同步、迁移和备份。以下是 MongoShake 的主要作用:

  1. 数据同步:MongoShake 可以将一个 MongoDB 数据库中的数据实时同步到另一个 MongoDB 数据库,保持数据的一致性。这对于构建多数据中心架构、实现高可用性和灾难恢复非常有用。

  2. 数据迁移:MongoShake 支持将一个 MongoDB 数据库中的数据迁移到另一个 MongoDB 数据库,包括全量数据和增量数据。这对于数据中心迁移、升级 MongoDB 版本或迁移至云端 MongoDB 服务等场景非常有用。

  3. 数据备份:MongoShake 可以将 MongoDB 数据库中的数据备份到另一个 MongoDB 实例,确保数据的安全性和可靠性。备份数据可以用于紧急恢复、数据分析或长期存储。

  4. 数据分发:MongoShake 支持将一个 MongoDB 数据库中的数据分发到多个目标 MongoDB 数据库,实现数据的复制和分发。

  5. 故障转移:当 MongoDB 主节点发生故障时,MongoShake 可以自动将从节点提升为新的主节点,确保系统的可用性和数据的连续性。

总的来说,MongoShake 是一个功能强大的 MongoDB 数据复制工具,可以帮助用户实现数据同步、迁移、备份和分发,提高 MongoDB 数据库的可用性、可靠性和灵活性。

迁移配置

1、从MongoDB分片集群版同步到MongoDB分片集群版

需改动的如下:
vim collector.conf
# 源端shard地址:
mongo_urls = mongodb://username1:password1@10.1.1.1:1001,10.1.1.2:2002,10.1.1.3:3003/admin;mongodb://username2:password2@10.2.2.1:1001,10.2.2.2:2002,10.2.2.3:3003/admin
# 源端sharding的cs的地址:
mongo_cs_url = mongodb://username1:password1@10.5.5.5:5555,10.5.5.6:5556/admin
# 源端mongos地址
mongo_s_url = mongodb://username_s:password_s@10.1.1.10:1010/admin
# all 表示全量+增量,full表示仅全量,incr表示仅增量
sync_mode = all 
# 目标mongos地址
incr_sync.tunnel.address = mongodb://username:password@20.1.1.1:2021,username:password@20.2.2.2:2022,username:password@20.3.3.3:3033
# 拉取增量的方式
incr_sync.mongo_fetch_method = oplog
# checkpoint写入的地址,默认对于写入源端,不填写即可
checkpoint.storage.url = 
# 阿里云MongoDB serverless集群请配置aliyun_serverless,自建的不需要配置
special.source.db.flag =
# 白名单迁移的集合
filter.namespace.white =test.table1


执行迁移:
[root@sql-audit-20230526 mongo-shake-v2.8.4]# ./collector.linux  -conf=collector.conf -verbose 0


注意事项:
  如果该集合迁移后,打算重新再次迁移该集合,需要手动删除源库mongoshake中ckpt_default集合,否则在此迁移,全量数据迁移不全,增量数据没有问题。

2、从只暴露mongos地址的MongoDB分片集群版同步到MongoDB分片集群版

# 源端mongos地址
mongo_s_url = mongodb://username1:password1@10.1.1.1:1001,username1:password1@10.1.1.2:2002,username1:password1@10.1.1.3:3003/admin?connect=direct
# all 表示全量+增量,full表示仅全量,incr表示仅增量
sync_mode = all
# 目标mongos地址
tunnel.address = mongodb://username:password@20.1.1.1:2021,username:password@20.2.2.2:2022,username:password@20.3.3.3:3033/admin
# 这里只可以为change_stream,支持>=4.0.1版本。
incr_sync.mongo_fetch_method = change_stream 
# checkpoint写入的地址,默认对于写入源端,不填写即可
checkpoint.storage.url = 
# 阿里云MongoDB serverless集群请配置aliyun_serverless,自建的不需要配置
special.source.db.flag =
# 白名单迁移的集合
filter.namespace.white =test.table1

3、从MongoDB副本集同步到MongoDB副本集

# 源端连接串信息
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003/admin 
# all 表示全量+增量,full表示仅全量,incr表示仅增量
sync_mode = all 
#目的端连接串信息
incr_sync.tunnel.address = mongodb://username:password@10.5.5.5:5005,10.6.6.6:6006,10.7.7.7:7007/admin 
# 如果希望以change stream拉取,该值需要配置change_stream,支持>=4.0.1版本。
incr_sync.mongo_fetch_method = oplog 
# checkpoint写入的地址,默认对于写入源端,不填写即可
checkpoint.storage.url = 
# 阿里云MongoDB serverless集群请配置aliyun_serverless,自建的不需要配置
special.source.db.flag =
# 白名单迁移的集合
filter.namespace.white =test.table1

4、从MongoDB副本集同步到MongoDB分片集群版

# 源端连接串信息
mongo_urls = mongodb://username:password@10.1.1.1:1001,10.2.2.2:2002,10.3.3.3:3003/admin
# all 表示全量+增量,full表示仅全量,incr表示仅增量
sync_mode = all 
# 目标mongos地址
incr_sync.tunnel.address = mongodb://username:password@20.1.1.1:2021,username:password@20.2.2.2:2022,username:password@20.3.3.3:3033/admin 
# 如果希望以change stream拉取,该值需要配置change_stream,支持>=4.0.1版本。
incr_sync.mongo_fetch_method = oplog
# checkpoint写入的地址,默认对于写入源端,不填写即可
checkpoint.storage.url = 
# 阿里云MongoDB serverless集群请配置aliyun_serverless,自建的不需要配置
special.source.db.flag =
# 白名单迁移的集合
filter.namespace.white =test.table1

5、从MongoDB集群版同步到MongoDB副本集

需改动的如下:
vim collector.conf
# 源端shard地址:
mongo_urls = mongodb://username1:password1@10.1.1.1:1001,10.1.1.2:2002,10.1.1.3:3003/admin;mongodb://username2:password2@10.2.2.1:1001,10.2.2.2:2002,10.2.2.3:3003/admin
# 源端sharding的cs的地址:
mongo_cs_url = mongodb://username1:password1@10.5.5.5:5555,10.5.5.6:5556/admin
# 源端mongos地址
mongo_s_url = mongodb://username_s:password_s@10.1.1.10:1010/admin
# all 表示全量+增量,full表示仅全量,incr表示仅增量
sync_mode = all 
# 目的端连接串信息
incr_sync.tunnel.address = mongodb://username:password@10.5.5.5:5005,10.6.6.6:6006,10.7.7.7:7007/admin 
# 如果希望以change stream拉取,该值需要配置change_stream,支持>=4.0.1版本。
incr_sync.mongo_fetch_method = oplog
# 由于是多个分片同步到一个,所以这里不能置为true 
full_sync.collection_exist_drop = false 
# checkpoint写入的地址,默认对于写入源端,不填写即可
checkpoint.storage.url = 
# 阿里云MongoDB serverless集群请配置aliyun_serverless,自建的不需要配置
special.source.db.flag =
# 白名单迁移的集合
filter.namespace.white =test.table1

6、阿里云云上MongoDB副本集的双向同步

云上副本集的双向同步可以参考副本集的单向同步,但是需要注意的有以下几点,假设A和B之间双向同步:

  1. 需要搭建2个mongoshake,一个从A到B,另一个从B到A

  2. 两条mongoshake不能同时用全量+增量(all)模式,正常应该是一个库为空(假设B),另一个有数据。那么从A到B先发起一次全量+增量同步,等待全量同步完毕以后,再从B到A发起一次增量同步。

  3. 双向同步需要依赖gid的开启,这个可以联系售后支持,开启gid将会重启实例造成秒级别闪断。

  4. 开启后将对应的gid配置在参数(incr_sync.oplog.gids里面,v2.4之前名字是oplog.gids),比如源端A的gid是100,目的端是B的gid是200,那么从A->B的MongoShake链路请配置incr_sync.oplog.gids = 100,从B到A的请配置incr_sync.oplog.gids = 200。

  5. gid用于记录数据的产生地,比如从A产生的数据导入到B以后,不会被再导入回A,这样就不会产生环形复制。需要注意的是,这个gid只能用于增量,这也是第2条为什么一个方向通道是全量+增量,另一个方向通道需要搭建增量的原因。

  6. 云下开源的mongodb不能使用双向同步,因为gid的修改是在内核里面,所以开源不支持。

  7. sharding同样也支持双向同步

7、实现MongoDB实例间的延迟同步

执行vi collector.conf命令配置MongoShake。各参数说明请参见MongoShake参数表。找到incr_sync.target_delay参数,根据实际业务需求设置该参数的值,单位为秒。本示例中将延迟时间设置为30分钟。

incr_sync.target_delay = 1800

运行后,此时您在源DB中执行的任何更改,都将会在30分钟后同步到从实例。

checkpoint存储的信息,在源库mongoshake中

edafb9754310550bfc34ad04187e7ec7.png

-verbose参数:

  • 当参数设置为 0 时,日志将仅输出到文件中。

  • 当参数设置为 1 时,日志将同时输出到文件和标准输出(stdout)中。

  • 当参数设置为 2 时,日志将仅输出到标准输出中。

配置文件详解

# 当前配置文件的版本号,请不要修改该值。
conf.version = 10


# --------------------------- global configuration ---------------------------
# collector name
# id用于输出pid文件等信息,以防止同一个目录下有多个mongoshake同时启动
id = mongoshake


# 是否启动主备模式。false表示只能启动1个mongoshake。配置true的话,用户可以启动2个mongoshake,拉取同一个源MongoDB,mongoshake将会自动选主,
备在监测到主挂掉后,会接管过同步服务。注意,如果主是在全量同步阶段挂掉,那么备接管过服务是不会进行断点续传,而是会从头开始同步,而且如果配置项
不当,可能还会有报错。主备模式主要用于在增量环节的HA容错切换
master_quorum = false


# 全量和增量的restful监控端口,可以用curl查看内部监控metric统计情况。
# `curl 127.0.0.1:9100`.
# usage: `./mongoshake-stat --port=9100`
full_sync.http_port = 9101
incr_sync.http_port = 9100
# profiling on net/http/profile
# golang pprof端口,可以用户查看内部运行堆栈信息
system_profile_port = 9200


# 日志的级别:debug, info, warning, error
log.level = info
# log和pid文件的目录,如果不设置默认打到当前路径的logs目录。
log.dir =
# log文件名。
log.file = collector.log
# log是否及时缓存一部分再刷盘打印,默认为false以保证程序运行的性能,但可能程序中间崩溃退出,有部分log没有打印出来。
true的话对于每条log都会进行刷盘,但是会降低部分性能。默认false。
log.flush = false




# 同步模式,all表示全量+增量同步,full表示全量同步,incr表示增量同步。
sync_mode = all


# 源MongoDB连接串信息,逗号分隔同一个副本集内的结点,分号分隔分片sharding实例,免密模式
# 可以忽略“username:password@”,注意,密码里面不能含有'@'符号。
# 副本集:mongodb://username1:password1@primaryA,secondaryB,secondaryC
# 分片集shard:mongodb://username1:password1@primaryA,secondaryB,secondaryC;mongodb://username2:password2@primaryX,secondaryY,secondaryZ
mongo_urls = mongodb://username:password@127.0.0.1:20040,127.0.0.1:20041


# 源MongoDB的config server的地址,如果源端是sharding,需要填写这个配置。默认空。
mongo_cs_url =


# 如果源端采用change stream拉取,这里还需要配置至少一个mongos的地址,多个mongos地址以逗号(,)分割
# 源MongoDB的mongos地址,如果源端是sharding,需要填写这个配置
mongo_s_url = 
# enable source ssl
mongo_ssl_root_ca_file = 


# 通道类型,direct表示目的端对接的是MongoDB,rpc,file,kafka用于远程传输,mock仅用于调试。默认direct。
tunnel = direct
# tunnel target resource url
# 对于rpc,此处配置目的端receiver的rpc接收地址
# 对于tcp,此处配置目的端receiver的tcp接收地址。
# 对于file,此处配置文件的路径,比如data。
# 对于kafka,此处配置kafka的地址,例如topic@brokers1,brokers2,默认的topic是mongoshake,目前partition只用到0。
# direct模式用于直接写入MongoDB,其余模式用于一些分析,或者远距离传输场景,
# 注意,如果是非direct模式,需要通过receiver进行解析,具体参考FAQ文档。
# 此处配置通道的地址,格式与mongo_urls对齐。
#///需修改
tunnel.address = mongodb://127.0.0.1:20080


# 通道数据的类型,只用于kafka和file通道类型。
# raw是默认的类型,其采用聚合的模式进行写入和
# 读取,但是由于携带了一些控制信息,所以需要专门用receiver进行解析。
# json以json的格式写入kafka,便于用户直接读取。
# bson以bson二进制的格式写入kafka。通常情况,对于非kafka通道,用户不需要关注该参数
#///需修改
tunnel.message = raw
# how many partitions will be written, use some hash function in "incr_sync.shard_key".
# 如果目的端是kafka,最多启用多少个partition,最大不超过"incr_sync.worker"。默认1
tunnel.kafka.partition_number = 1
# tunnel json format, it'll only take effect in the case of tunnel.message = json
# and tunnel == kafka. Set canonical_extended_json if you want to use "Canonical
# Extended JSON Format", #559.
# 写入异构通道的json格式。如果希望使用Canonical Extended Json Format,则设置为
# canonical_extended_json
tunnel.json.format =
# if tunnel == driect or kafka and enable ssl
tunnel.mongo_ssl_root_ca_file =


# 连接模式,primary表示从主上拉取,secondaryPreferred表示优先从secondary拉取(默认建议值),
# standalone表示从任意单个结点拉取。
mongo_connect_mode = secondaryPreferred




# 黑白名单过滤,目前不支持正则,白名单表示通过的namespace,黑名单表示过滤的namespace,
# 不能同时指定。分号分割不同namespace,每个namespace可以是db,也可以是db.collection。
#例如,我想只通过db1,db2和db3中的collection1,那么配置filter.namespace.white=db1;db2;db3.collection1即可
filter.namespace.black =
filter.namespace.white =


# 正常情况下,不建议配置该参数,但对于有些非常特殊的场景,用户可以启用admin,mongoshake等库的同步,
# 以分号分割,例如:admin;mongoshake。
filter.pass.special.db =


# 是否需要开启DDL同步,true表示开启,源是sharding暂时不支持开启。
# 如果目的端是sharding,暂时不支持applyOps命令,包括事务。
filter.ddl_enable = false


# 如果MongoDB启用了gid,但是目的端MongoDB不支持gid导致同步会失败,可以启用gid过滤,将会去掉gid字段。
# 谨慎建议开启,shake本身性能受损很大。
filter.oplog.gids = false




# checkpoint存储信息,用于支持断点续传。
# checkpoint的具体写入的MongoDB地址,如果不配置,对于副本集和分片集群都将写入源库(db=mongoshake)
# 2.4版本以后不需要配置为源端cs的地址。
checkpoint.storage.url =


# checkpoint存储的db的名字
checkpoint.storage.db = mongoshake


# checkpoint存储的表的名字,如果启动多个mongoshake拉取同一个源可以修改这个表名以防止冲突。
checkpoint.storage.collection = ckpt_default


# set if enable ssl
checkpoint.storage.url.mongo_ssl_root_ca_file = 
# 本次开始拉取的位置,如果checkpoint已经存在(位于上述存储位置)则该参数无效,
# 如果需要强制该位置开始拉取,需要先删除原来的checkpoint,详见FAQ。
# 若checkpoint不存在,且该值为1970-01-01T00:00:00Z,则会拉取源端现有的所有oplog。
# 若checkpoint不存在,且该值不为1970-01-01T00:00:00Z,则会先检查源端oplog最老的时间是否
# 大于给定的时间,如果是则会直接报错退出。
checkpoint.start_position = 1970-01-01T00:00:00Z


# transform: fromDbName1.fromCollectionName1:toDbName1.toCollectionName1;fromDbName2:toDbName2
# 转换命名空间,比如a.b同步后变成c.d,谨慎建议开启,比较耗性能。
transform.namespace =


# --------------------------- full sync configuration ---------------------------
# 并发最大拉取的表个数,例如,6表示同一时刻shake最多拉取6个表。
full_sync.reader.collection_parallel = 6
# 同一个表内并发写的线程数,例如,8表示对于同一个表,将会有8个写线程进行并发写入。
full_sync.reader.write_document_parallel = 8
# 目的端写入的batch大小,例如,128表示一个线程将会一次聚合128个文档然后再写入。
full_sync.reader.document_batch_size = 128
# 源端拉取batch中最大条数
full_sync.reader.fetch_batch_size = 8192
# max number of fetching thread per table. default is 1
# 单个表最大拉取的线程数,默认是单线程拉取。需要具备splitVector权限。
# 注意:对单个表来说,仅支持索引对应的value是同种类型,如果有不同类型请勿启用该配置项!
full_sync.reader.parallel_thread = 1
# 如果设置了full_sync.reader.parallel_thread,还需要设置该参数,并行拉取所扫描的index,value
# 必须是同种类型。对于副本集,建议设置_id;对于集群版,建议设置shard_key。key只能有1个field。
full_sync.reader.parallel_index = _id




# 同步时如果目的库存在,是否先删除目的库再进行同步,true表示先删除再同步,false表示不删除。
full_sync.collection_exist_drop = true




# 全量期间数据同步完毕后,是否需要创建索引,none表示不创建,foreground表示创建前台索引,
# background表示创建后台索引。
full_sync.create_index = none




# 如果_id存在在目的库,是否将insert语句修改为update语句。
full_sync.executor.insert_on_dup_update = false


# 源端是sharding,是否需要过滤orphan文档
full_sync.executor.filter.orphan_document = false


# 全量阶段写入端是否启用majority write
full_sync.executor.majority_enable = false


# --------------------------- incrmental sync configuration ---------------------------
# 从源MongoDB拉取增量的方式,oplog(默认)表示以oplog进行拉取,change_stream表示以change stream进行对接拉取。oplog方式支持所有大于等于3.0的MongoDB版本,
但对于sharding的同步,需要关掉balancer进行同步,否则会有时序不一致的问题。change_stream支持大于等于4.0的MongoDB版本,对于部分DDL的同步不支持,目前只支持
库表的建/删,重命名,由于MongoDB本身的限制(不支持在ChangeStream输出这些命令),对于建/删索引,convertToCapped,applyOps等都不支持。默认oplog。
#oplog方式,对于sharding的同步,需要关掉balancer进行同步
incr_sync.mongo_fetch_method = oplog




# 更新文档后,只需要更新的字段则设为false,需要全部文档内容则设为true
# 只在mongo_fetch_method = change_stream 模式下生效,且性能有所下降
incr_sync.change_stream.watch_full_document = false


# 双向同步
# 开源请忽略,gid用于双活防止环形复制,目前只用于阿里云云上MongoDB,如果是阿里云云上实例互相同步
# 希望开启gid,请联系阿里云售后,sharding的有多个gid请以分号(;)分隔。
incr_sync.oplog.gids =


# hash的方式,id表示按文档hash,collection表示按表hash,auto表示自动选择hash类型。
# 如果没有索引建议选择id达到非常高的同步性能,反之请选择collection。
incr_sync.shard_key = collection


# 对于按collection哈希,如果某些表不具有唯一索引,则可以设置按_id哈希以提高并发度。
# 用户需要确认该表不会创建唯一索引,一旦检测发现存在唯一索引,则会立刻crash退出。
# 例如,db1.collection1;db2.collection2,不支持仅指定db
incr_sync.shard_by_object_id_whitelist = 




# 内部发送(写目的DB)的worker数目,如果机器性能足够,可以提高worker个数。
incr_sync.worker = 8




# 对于目的端是kafka等非direct tunnel,启用多少个序列化线程,必须为"incr_sync.worker"的倍数。
# 默认为"incr_sync.worker"的值。
incr_sync.tunnel.write_thread = 8




# 设置目的端的延迟,比如延迟源端20分钟,目的端可以落后于源端指定的秒数,类似MongoDB本身主从同步slaveDelay参数,单位:秒
# 0表示不启用
incr_sync.target_delay = 0




# 内部队列的配置参数,如果目前性能足够不建议修改,详细信息参考FAQ。
# batch_queue_size:每个worker线程的队列长度,worker线程从此队列取任务
# batching_max_size:一次分发给worker的任务最多包含多少个文档
# buffer_capacity:PendingQueue队列中一个buffer至少包含的文档个数,进行序列化
incr_sync.worker.batch_queue_size = 64
incr_sync.adaptive.batching_max_size = 1024
incr_sync.fetcher.buffer_capacity = 256
incr_sync.reader.fetch_batch_size = 8192


# --- direct tunnel only begin ---
# if tunnel type is direct, all the below variable should be set
# 下列参数仅用于tunnel为direct的情况。


# 如果目的端是sharding,不能开启该参数,如果_id不存在在目的库,是否将update语句修改为insert语句。
incr_sync.executor.upsert = false


# 如果_id存在在目的库,是否将insert语句修改为update语句。
incr_sync.executor.insert_on_dup_update = false


# 如果写入存在冲突,记录冲突的文档。选项:db, none
# db:冲突写到目的DB的mongshake_conflict库中,none:表示不记录冲突文档
incr_sync.conflict_write_to = none




# 增量阶段写入端是否启用majority write
incr_sync.executor.majority_enable = false


# --- direct tunnel only end ---


# 特殊字段,标识源端类型,默认为空。阿里云MongoDB serverless集群请配置aliyun_serverless
special.source.db.flag =


# 特殊字段,当源库和目标库都是分片集群时,且源表和目标表片键不一致,是否跳过检验
#例如,db1.collection1;db2.collection2
skip.nsshardkey.verify =

注意事项

如果同一个库或集合迁移后,打算重新再次迁移,需要手动删除源库mongoshake中ckpt_default集合,否则在此迁移,全量数据迁移不全,增量数据没有问题。

加入数据库技术交流群:

cc7382fdd284194df92c9eb1b4f3c4f8.png

进群福利:

1、知识共享与学习机会

2、问题求助与解决支持

3、技术沉淀和分享平台

4、及时了解行业动态

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值