MongoShake迁移同步MongoDB

13 篇文章 0 订阅
12 篇文章 1 订阅

MongoShake迁移同步MongoDB

简介:

        Mongo-Shake 由阿里云 Nosql 团队开发和维护。Mongo-Shake 是基于 MongoDB 的 oplog 的通用服务平台。它从源 mongo 数据库中获取 oplog,并在目标 mongo 数据库中重放或发送到不同隧道的其他端。如果目标端是mongo数据库,即直接replay oplog,它就像一个同步工具,用于将数据从源MongoDB复制到另一个MongoDB,以构建冗余复制或双活复制。

        除了这种直接方式,还有其他隧道类型,如 rpc、file、tcp、kafka。用户编写的接收器必须定义自己的接口来分别连接到这些隧道。用户还可以定义自己的可插拔隧道类型。如果连接到kafka这样的第三方消息中间件,消费者可以灵活地在pub/sub模块中异步获取订阅者数据。

        源可以是单个 mongod、副本集或分片,而目标可以是 mongod 或 mongos。如果源是副本集,官方建议从次要/隐藏中获取数据以减轻主要压力。如果源是分片,每个分片都应该连接到 Mongo-Shake。目标端可以有多个 mongos 以保持高可用性,不同的数据将被散列并写入不同的 mongos。

一、MongoShake应用场景举例:

    1.  MongoDB集群间数据的异步复制,免去业务双写开销。
    2.  MongoDB集群间数据的镜像备份(当前1.0开源版本支持受限)
    3.  日志离线分析
    4.  日志订阅
    5.  数据路由。根据业务需求,结合日志订阅和过滤机制,可以获取关注的数据,达到数据路由的功能。
    6.  Cache同步。日志分析的结果,知道哪些Cache可以被淘汰,哪些Cache可以进行预加载,反向推动Cache的更新。
    7.  基于日志的集群监控

二、MongoShake功能介绍:

        MongoShake从源库抓取oplog数据,然后发送到各个不同的tunnel通道。源库支持:ReplicaSet,Sharding,Mongod,目的库支持:Mongos,Mongod。现有通道类型有:

    1.  Direct:直接写入目的MongoDB
    2.  RPC:通过net/rpc方式连接
    3.  TCP:通过tcp方式连接
    4.  File:通过文件方式对接
    5.  Kafka:通过Kafka方式对接
    6.  Mock:用于测试,不写入tunnel,抛弃所有数据

三、环境:

   环境: centos7 

   源库: mongodb 3.0.6(分片集群)

源库基本信息
主机IP地址端口备注
MongoDB1        10.0.8.74

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27017为primary
MongoDB210.0.8.75

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27019为primary
MongoDB310.0.8.76

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27018为primary

   目的库: mongodb 3.0.6(分片集群)

目的库基本信息
主机IP地址端口备注
MongoDB1        10.0.8.28

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27017为primary
MongoDB210.0.8.29

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27018为primary
MongoDB310.0.8.30

数据端口:27017、27018、27019

config端口:20000

mongos路由端口:30000

27019为primary

四、实操

1、下载安装mongoshake(可以在任意机器上安装,也可以在目的库mongodb机器),下载地址如下:

链接:https://pan.baidu.com/s/1xvps_mimptpxWvX_5GOk0g 
提取码:osyu

$ cd /data/service/mongoshake/
[ yukw @ harbor 10.0.8.54 ] /data/service/mongoshake
$ ll
总用量 37504
-rw-r--r-- 1 yukw yukw 38401575 8月  16 17:36 mongo-shake-v2.4.6.tar.gz
$ tar xf mongo-shake-v2.4.6.tar.gz 
$ ll

2、修改 collector.conf 配置文件

$ pwd
/data/service/mongoshake
$ cd mongo-shake-v2.4.6/
$ vim collector.conf 

下面是配置文件详细介绍,如果源库不是分片集群模式,而是单机或者副本集模式,那么配置文件里面的  mongo_cs_ur、mongo_s_url 则不需要配置。

从配置文件注释里面可以得出,如果你的mongodb配置了mongos路由,那么就认定是分片模式

# if you have any problem, please visit https://github.com/alibaba/MongoShake/wiki/FAQ
# for the detail explanation, please visit xxxx
# 如果有问题,请先查看FAQ文档以及wiki上的说明。
# 关于各个参数的详细说明,请参考:xxx

# current configuration version, do not modify.
# 当前配置文件的版本号,请不要修改该值。
conf.version = 4

# --------------------------- global configuration ---------------------------
# collector name
# id用于输出pid文件等信息。
id = mongoshake

# high availability option.
# enable master election if set true. only one mongoshake can become master
# and do sync, the others will wait and at most one of them become master once 
# previous master die. The master information stores in the `mongoshake` db in the source 
# database by default.
# This option is useless when there is only one mongoshake running.
# 如果开启主备mongoshake拉取同一个源端,此参数需要开启。
master_quorum = false

# http api interface. Users can use this api to monitor mongoshake.
# `curl 127.0.0.1:9100`.
# We also provide a restful tool named "mongoshake-stat" to
# print ack, lsn, checkpoint and qps information based on this api.
# usage: `./mongoshake-stat --port=9100`
# 全量和增量的restful监控端口,可以用curl查看内部监控metric统计情况。详见wiki。
full_sync.http_port = 9101
incr_sync.http_port = 9100
# profiling on net/http/profile
# profiling端口,用于查看内部go堆栈。
system_profile_port = 9200

# global log level: debug, info, warning, error. lower level message will be filter
log.level = info
# log directory. log and pid file will be stored into this file.
# if not set, default is "./logs/"
# log和pid文件的目录,如果不设置默认打到当前路径的logs目录。
log.dir = /data/service/mongoshake/mongo-shake-v2.4.6/logs
# log file name.
# log文件名。
log.file = collector.log
# log flush enable. If set false, logs may not be print when exit. If
# set true, performance will be decreased extremely
# 设置log刷新,false表示包含缓存,如果true那么每条log都会直接刷屏,但对性能有影响;
# 反之,退出不一定能打印所有的log,调试时建议配置true。
log.flush = false

# sync mode: all/full/incr. default is incr.
# all means full synchronization + incremental synchronization.
# full means full synchronization only.
# incr means incremental synchronization only.
# 同步模式,all表示全量+增量同步,full表示全量同步,incr表示增量同步。
sync_mode = all

# connect source mongodb, set username and password if enable authority. Please note: password shouldn't contain '@'.
# split by comma(,) if use multiple instance in one replica-set. E.g., mongodb://username1:password1@primaryA,secondaryB,secondaryC
# split by semicolon(;) if sharding enable. E.g., mongodb://username1:password1@primaryA,secondaryB,secondaryC;mongodb://username2:password2@primaryX,secondaryY,secondaryZ
# 源MongoDB连接串信息,逗号分隔同一个副本集内的结点,分号分隔分片sharding实例,免密模式
# 可以忽略“username:password@”,注意,密码里面不能含有'@'符号。
# 举例:
# 副本集:mongodb://username1:password1@primaryA,secondaryB,secondaryC
# 分片集:mongodb://username1:password1@primaryA,secondaryB,secondaryC;mongodb://username2:password2@primaryX,secondaryY,secondaryZ
mongo_urls = mongodb://yukw27017:Yukw27017@10.0.8.74:27017,10.0.8.75:27017,10.0.8.76:27017;mongodb://yukw27018:Yukw27018@10.0.8.76:27018,10.0.8.74:27018,10.0.8.75:27018;mongodb://yukw27019:Yukw27019@10.0.8.75:27019,10.0.8.74:27019,10.0.8.76:27019
# please fill the source config server url if source mongodb is sharding.
mongo_cs_url = mongodb://yukw20000:Yukw20000@10.0.8.74:20000
# please give at least one mongos address if source is sharding.
# 如果源端采用change stream拉取,这里还需要配置至少一个mongos的地址,多个mongos地址以逗号(,)分割
mongo_s_url = mongodb://yukw30000:Yukw30000@10.0.8.74:30000,10.0.8.75:30000,10.0.8.76:30000

# tunnel pipeline type. now we support rpc,file,kafka,mock,direct
# 通道模式。
tunnel = direct
# tunnel target resource url
# for rpc. this is remote receiver socket address
# for tcp. this is remote receiver socket address
# for file. this is the file path, for instance "data"
# for kafka. this is the topic and brokers address which split by comma, for
# instance: topic@brokers1,brokers2, default topic is "mongoshake"
# for mock. this is uesless
# for direct. this is target mongodb address which format is the same as `mongo_urls`. If
# the target is sharding, this should be the mongos address.
# direct模式用于直接写入MongoDB,其余模式用于一些分析,或者远距离传输场景,
# 注意,如果是非direct模式,需要通过receiver进行解析,具体参考FAQ文档。
# 此处配置通道的地址,格式与mongo_urls对齐。
#tunnel.address = mongodb://root:nsw123456@10.0.8.54:27017
tunnel.address = mongodb://root:Cs-20200220!@10.0.8.28:30000,10.0.8.29:30000,10.0.8.30:30000
# the message format in the tunnel, used when tunnel is kafka.
# "raw": batched raw data format which has good performance but encoded so that users
# should parse it by receiver.
# "json": single oplog format by json.
# "bson": single oplog format by bson.
# 通道数据的类型,只用于kafka和file通道类型。
# raw是默认的类型,其采用聚合的模式进行写入和
# 读取,但是由于携带了一些控制信息,所以需要专门用receiver进行解析。
# json以json的格式写入kafka,便于用户直接读取。
# bson以bson二进制的格式写入kafka。
tunnel.message = raw

# connect mode:
# primary: fetch data from primary.
# secondaryPreferred: fetch data from secondary if has, otherwise primary.(default)
# standalone: fetch data from given 1 node, no matter primary, secondary or hidden. This is only
# support when tunnel type is direct.
# 连接模式,primary表示从主上拉取,secondaryPreferred表示优先从secondary拉取(默认建议值),
# standalone表示从任意单个结点拉取。
mongo_connect_mode = secondaryPreferred

# filter db or collection namespace. at most one of these two parameters can be given.
# if the filter.namespace.black is not empty, the given namespace will be
# filtered while others namespace passed. 
# if the filter.namespace.white is not empty, the given namespace will be
# passed while others filtered. 
# all the namespace will be passed if no condition given.
# db and collection connected by the dot(.).
# different namespaces are split by the semicolon(;).
# filter: filterDbName1.filterCollectionName1;filterDbName2
# 黑白名单过滤,目前不支持正则,白名单表示通过的namespace,黑名单表示过滤的namespace,
# 不能同时指定。分号分割不同namespace,每个namespace可以是db,也可以是db.collection。
filter.namespace.black =
## 开启白名单,仅同步 test_cms 数据库,如果为空,则默认同步除了admin,local, config以外的所有库
filter.namespace.white = test_cms 
# some databases like "admin", "local", "mongoshake", "config", "system.views" are
# filtered, users can enable these database based on some special needs.
# different database are split by the semicolon(;).
# e.g., admin;mongoshake.
# pay attention: collection isn't support like "admin.xxx" except "system.views"
# 正常情况下,不建议配置该参数,但对于有些非常特殊的场景,用户可以启用admin,mongoshake等库的同步,
# 以分号分割,例如:admin;mongoshake。
filter.pass.special.db =
# only transfer oplog commands for syncing. represent
# by oplog.op are "i","d","u".
# DDL will be transferred if disable like create index, drop databse,
# transaction in mongodb 4.0.
# 是否需要开启DDL同步,true表示开启,源是sharding暂时不支持开启,(sharding不开启默认支持DDL同步,博主已经实验过了)。
# 如果目的端是sharding,暂时不支持applyOps命令,包括事务。
filter.ddl_enable = false
# checkpoint info, used in resuming from break point.
# checkpoint存储信息,用于支持断点续传。
# context.storage.url is used to mark the checkpoint store database. E.g., mongodb://127.0.0.1:20070
# if not set, checkpoint will be written into source mongodb when source mongodb is replica-set(db=mongoshake),
# when source mongodb is sharding, the checkpoint will be written into config-server(db=admin)
# checkpoint的具体写入的MongoDB地址,如果不配置,对于副本集将写入源库(db=mongoshake),对于分片集
# 将写入config-server(db=admin)
checkpoint.storage.url =
# checkpoint db's name.
# checkpoint存储的db的名字
checkpoint.storage.db = mongoshake
# checkpoint collection's name.
# checkpoint存储的表的名字,如果启动多个mongoshake拉取同一个源可以修改这个表名以防止冲突。
checkpoint.storage.collection = ckpt_default
# real checkpoint: the fetching oplog position.
# pay attention: this is UTC time which is 8 hours latter than CST time. this
# variable will only be used when checkpoint is not exist.
# 本次开始拉取的位置,如果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 from source db or collection namespace to dest db or collection namespace.
# at most one of these two parameters can be given.
# transform: fromDbName1.fromCollectionName1:toDbName1.toCollectionName1;fromDbName2:toDbName2
# 转换命名空间,比如a.b同步后变成c.d,谨慎建议开启,比较耗性能。
transform.namespace =

# --------------------------- full sync configuration ---------------------------
# the number of collection concurrence
# 并发最大拉取的表个数,例如,6表示同一时刻shake最多拉取6个表。
full_sync.reader.collection_parallel = 10
# the number of document writer thread in each collection.
# 同一个表内并发写的线程数,例如,8表示对于同一个表,将会有8个写线程进行并发写入。
full_sync.reader.write_document_parallel = 16
# number of documents in a batch insert in a document concurrence
# 目的端写入的batch大小,例如,128表示一个线程将会一次聚合128个文档然后再写入。
full_sync.reader.document_batch_size = 128

# drop the same name of collection in dest mongodb in full synchronization
# 同步时如果目的库存在,是否先删除目的库再进行同步,true表示先删除再同步,false表示不删除。
full_sync.collection_exist_drop = true

# create foreground indexes when data sync finish in full sync stage.
# 全量期间数据同步完毕后,是否需要创建索引,none表示不创建,foreground表示创建前台索引,
# background表示创建后台索引。
full_sync.create_index = none

# convert insert to update when duplicate key found
# 如果_id存在在目的库,是否将insert语句修改为update语句。
full_sync.executor.insert_on_dup_update = false
# filter orphan document for source type is sharding.
# 源端是sharding,是否需要过滤orphan文档
full_sync.executor.filter.orphan_document = false
# enable majority write in full sync.
# the performance will degrade if enable.
# 全量阶段写入端是否启用majority write
full_sync.executor.majority_enable = false

# --------------------------- incrmental sync configuration ---------------------------
# fetch method:
# oplog: fetch oplog from source mongodb (default)
# change_stream: use change to receive change event from source mongodb, support MongoDB >= 4.0
incr_sync.mongo_fetch_method = oplog

# global id. used in active-active replication.
# this parameter is not supported on current open-source version.
# gid用于双活防止环形复制,目前只用于阿里云云上MongoDB,如果是阿里云云上实例互相同步
# 希望开启gid,请联系阿里云售后,sharding的有多个gid请以分号(;)分隔。
incr_sync.oplog.gids =

# distribute data to different worker by hash key to run in parallel.
# [auto] 		decide by if there has unique index in collections.
# 		 		use `collection` if has unique index otherwise use `id`.
# [id] 			shard by ObjectId. handle oplogs in sequence by unique _id
# [collection] 	shard by ns. handle oplogs in sequence by unique ns
# hash的方式,id表示按文档hash,collection表示按表hash,auto表示自动选择hash类型。
# 如果没有索引建议选择id达到非常高的同步性能,反之请选择collection。
incr_sync.shard_key = collection

# oplog transmit worker concurrent
# if the source is sharding, worker number must equal to shard numbers.
# 内部发送的worker数目,如果机器性能足够,可以提高worker个数。
incr_sync.worker = 8
# batched oplogs have block level checksum value using
# crc32 algorithm. and compressor for compressing content
# of oplog entry.
# supported compressor are : gzip,zlib,deflate
# Do not enable this option when tunnel type is "direct"
# 是否启用发送,非direct模式发送可以选择压缩以减少网络带宽消耗。
incr_sync.worker.oplog_compressor = none

# set the sync delay just like mongodb secondary slaveDelay parameter. unit second.
# 设置目的端的延迟,比如延迟源端20分钟,类似MongoDB本身主从同步slaveDelay参数,单位:秒
# 0表示不启用
incr_sync.target_delay = 0

# memory queue configuration, plz visit FAQ document to see more details.
# do not modify these variables if the performance and resource usage can
# meet your needs.
# 内部队列的配置参数,如果目前性能足够不建议修改,详细信息参考FAQ。
incr_sync.worker.batch_queue_size = 64
incr_sync.adaptive.batching_max_size = 1024
incr_sync.fetcher.buffer_capacity = 256

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

# oplog changes to Insert while Update found non-exist (_id or unique-index)
# 如果_id不存在在目的库,是否将update语句修改为insert语句。
incr_sync.executor.upsert = false
# oplog changes to Update while Insert found duplicated key (_id or unique-index)
# 如果_id存在在目的库,是否将insert语句修改为update语句。
incr_sync.executor.insert_on_dup_update = false
# db. write duplicated logs to mongoshake_conflict
# sdk. write duplicated logs to sdk.
# 如果写入存在冲突,记录冲突的文档。
incr_sync.conflict_write_to = none

# enable majority write in incrmental sync.
# the performance will degrade if enable.
# 增量阶段写入端是否启用majority write
incr_sync.executor.majority_enable = false

# --- direct tunnel only end ---

3、启动mongoshake服务

$ cd /data/service/mongoshake/mongo-shake-v2.4.6/
$ ./collector.linux -conf=collector.conf

4、验证

查看日志

$ cd /data/service/mongoshake/mongo-shake-v2.4.6/logs
$ ll
总用量 3064
-rw-rw---- 1 yukw yukw  425752 8月  18 17:56 collector.log
-rw-rw---- 1 yukw yukw  262126 8月  18 17:04 collector.log.1
-rw-rw---- 1 yukw yukw    1999 8月  18 16:26 collector.log.2
-rw-rw---- 1 yukw yukw 1929455 8月  17 23:59 collector.log.2021-08-17.001
-rw-rw---- 1 yukw yukw    1999 8月  18 16:21 collector.log.3
-rw------- 1 yukw yukw       5 8月  18 17:15 mongoshake.pid
$ cat collector.log
....................................................................
............................忽略...................................
[2021/08/18 17:04:16 CST] [INFO] [common.(*MongoConn).Close:78] Close session with mongodb://yukw27017:***@10.0.8.74:27017,10.0.8.75:27017,10.0.8.76:27017
[2021/08/18 17:04:16 CST] [INFO] [common.NewMongoConn:73] New session to mongodb://yukw27018:***@10.0.8.76:27018,10.0.8.74:27018,10.0.8.75:27018 successfully
[2021/08/18 17:04:16 CST] [INFO] [common.(*MongoConn).Close:78] Close session with mongodb://yukw27018:***@10.0.8.76:27018,10.0.8.74:27018,10.0.8.75:27018
[2021/08/18 17:04:16 CST] [INFO] [common.NewMongoConn:73] New session to mongodb://yukw27018:***@10.0.8.76:27018,10.0.8.74:27018,10.0.8.75:27018 successfully
[2021/08/18 17:04:16 CST] [INFO] [common.(*MongoConn).Close:78] Close session with mongodb://yukw27018:***@10.0.8.76:27018,10.0.8.74:27018,10.0.8.75:27018
[2021/08/18 17:04:16 CST] [INFO] [common.NewMongoConn:73] New session to mongodb://yukw27019:***@10.0.8.75:27019,10.0.8.74:27019,10.0.8.76:27019 successfully
[2021/08/18 17:04:16 CST] [INFO] [common.(*MongoConn).Close:78] Close session with mongodb://yukw27019:***@10.0.8.75:27019,10.0.8.74:27019,10.0.8.76:27019
[2021/08/18 17:04:16 CST] [INFO] [common.NewMongoConn:73] New session to mongodb://yukw27019:***@10.0.8.75:27019,10.0.8.74:27019,10.0.8.76:27019 successfully
[2021/08/18 17:04:16 CST] [INFO] [common.(*MongoConn).Close:78] Close session with mongodb://yukw27019:***@10.0.8.75:27019,10.0.8.74:27019,10.0.8.76:27019
[2021/08/18 17:04:16 CST] [INFO] [coordinator.(*ReplicationCoordinator).serializeDocumentOplog:266] ------------------------full sync done!---------------
............................忽略..........................................
.........................................................................

也可以去目的库登录查看数据是否同步过来 

五. Q&A说明
此处记载几个常见的问题:

Q. mongoshake是否会同步config, local, admin库
A: 不会同步。如果用户一定要把admin的库同步到别的,那么可以通过命名转换功能(配置transform.namespace)把admin库同步到别的数据库,同时配置filter.pass.special.db参数:

filter.pass.special.db = admin
transform.namespace = admin.abc:target.abc # 把admin库下面的abc同步到target库的abc
Q. 从MongoDB同步到MongoDB发现全量阶段目的端MongoDB压力过大怎么办?
A: 用户可以降低全量同步配置replayer的相关参数,以降低目的端压力。

Q. 从MongoDB同步到MongoDB发现全量阶段同步时间过久,怎么办?
A: 用户可以定位一下看看目的慢的原因是什么,正常情况下可以提高全量配置replayer的相关参数,以提高全量同步的性能。但也有可能,问题的瓶颈是源端/网络端/通道cpu,内存等压力过高,都是有可能的。

Q. 到底什么是checkpoint?
A: checkpoint是记录增量同步的位点情况,mongoshake的启动就是根据这个位点来进行的,比如我们已经同步到10点钟了,那么这个时候挂掉了,如果没有位点,那么只能从头开始拉,位点的意义就是在于断点续传。在mongoshake中,位点信息是以64位时间戳来标记的(ts字段,准确的说是32位时间戳+计数),如果发生挂掉重启,那么会从源库的oplog表中寻找这个位点,并从此开始往后进行同步。
到这里,用户可能会问,那么mongoshake里面位点是存储在哪里的?存储的位置就是取决于用户context的相关配置,以副本集为例,checkpoint是存储于源库的mongoshake库的ckpt_default表,其大概内容长这个样子:

mongos> use mongoshake
switched to db mongoshake
mongos> show tables
ckpt_default
system.indexes
mongos> db.ckpt_default.find()
{ "_id" : ObjectId("611ccd0fb8c90d0bf0403248"), "name" : "shard1", "ckpt" : Timestamp(1629338632, 156), "version" : 2, "fetch_method" : "oplog", "oplog_disk_queue" : "", "oplog_disk_queue_apply_finish_ts" : Timestamp(0, 0) }
{ "_id" : ObjectId("611ccd10b8c90d0bf0403249"), "name" : "shard2", "ckpt" : Timestamp(1629163320, 1), "version" : 2, "fetch_method" : "", "oplog_disk_queue" : "", "oplog_disk_queue_apply_finish_ts" : Timestamp(0, 1) }
{ "_id" : ObjectId("611ccd10b8c90d0bf040324a"), "name" : "shard3", "ckpt" : Timestamp(1629338507, 1), "version" : 2, "fetch_method" : "oplog", "oplog_disk_queue" : "", "oplog_disk_queue_apply_finish_ts" : Timestamp(0, 0) }

其中ckpt对应的field就是checkpoint。
用户可能还会问,那么mongoshake的checkpoint是怎么存储的,什么时候会存储?答案是,checkpoint是定期存储的,如果有数据同步,那么checkpoint的更新会很频繁(秒级别);如果没有数据同步,比如这个时候用户源端就是没有写入,那么默认是分钟级别更新一次心跳checkpoint。假设mongoshake数据位点记录是10:00:00,但是数据已经同步到10:00:10,这个时候mongoshake挂掉了,下次会从10:00:00重新开始同步,由于DML本身具有幂等性,数据的重复回放是OK的。那么用户可能会问,DDL怎么办?参考下面问题。

Q. 如何同步DDL?DDL能保证幂等性吗?
A: 设置replayer.dml_only = false可以同步DDL。DDL不能保证幂等性。在mongoshake里面,如果发现是DDL语句,会卡一个全局的barrier,让当前DDL语句同步,然后再卡一个全局barrier,等当前DDL语句同步完成,再接着并发同步接下来的oplog,barrier的卡锁伴随着checkpoint的强制刷新。但是由于DDL同步和checkpoint的刷新并不是一个院子操作,如果用户恰好在同步DDL完成和checkpoint刷新之间,进程挂掉了,那么没有办法,重启以后肯定会持续报错,用户需要手动运维解决,比如跳过这个DDL,或者目的端近些一个反向操作(原来DDL是建库,需要进行删除库;原来是建索引,需要进行删索引操作)。但是,这个概率很低。

Q. mongoshake碰到同步出错的情况,会跳过这个错误,继续同步吗?
A: 不会,会持续报错,用户需要关注日志的运行情况。

Q. 除了日志如何知道目前mongoshake的同步情况?
A: mongoshake有提供restful接口,可以监控mongoshake的内部同步情况,参考wiki: How to monitor the MongoShake,正常情况下lsn_ckpt.time会一直增长,如果这个数值不增长了,那么就表示同步出现问题了。

Q. 全量同步是否会同步索引?
A: 会同步索引,显示全量同步,全量同步完毕后会同步索引,接着是增量同步。

Q. 选择all模式同步,如果挂掉以后重启,是否会重新发起一次全量同步?进入增量阶段,是否要修改为oplog增量模式,然后再重启?
A: 显示全量同步,全量同步完毕会写入checkpoint,然后进行增量同步,增量同步阶段会不断更新checkpoint。对于mongoshake来说,是否进行全量同步取决于checkpoint,如果checkpoint存在且合法,那么只会进入增量同步;否则,会先进行全量同步,然后是增量。那么checkpoint怎么知道是存在的,就是context里面的参数的位置决定;那么怎么知道checkpoint是合法的?如果最老的oplog的时间位点小于checkpoint,那么就是合法的,证明增量能接上。

Q. 我的数据量很大,几百G/几个T/几十个T,all模式同步有什么要注意的地方?
A: 最需要注意的就是,全量同步完毕,增量能否接上。mongoshake是根据oplog的位点来决定全量结束是否要进行增量,如果全量花了2天,但是oplog表只能存储1天,那么全量同步完毕以后mongoshake就会报错退出,这是因为增量的位点丢失了。所以如果全量很大,同步时间势必很久,那么就需要放大oplog的表的大小以维持增量oplog。
其他还需要注意的就是压力问题,如何选取适当的参数应对对于源端/目的端的压力,减少对业务的影响。用户也可以决定从一个hidden结点,护着一个独立的secondary结点进行拉取。

Q. 同步出现xxx错误,怎么办?
A: 这个我在github的wiki基本都有总结,可以先看下github的faq。如果里面没有提到的,可以提交issue进行反馈。

Q. 目前mongoshake有校验工具吗?
A: 目前script下面有个comparison.py的全量校验脚本校验数据的一致性。那么如何进行增量的校验呢?目前还没有,敬请期待。

Q. sharding模式同步有啥需要注意的吗?
A: 如果源端是sharding,那么目前需要关闭balancer,在v2.1非稳定版本里面,我们支持了不关闭balancer,用户可以进行试用,但是目前这个是非稳定版本。此外源端如果是sharding,DDL的同步(replayer.dml_only = false)不能开启。

Q. 我把数据写入到kafka,怎么从kafka中拉取数据,发现直接拉取出现乱码
A: 请先看下wiki: https://github.com/alibaba/MongoShake/wiki/FAQ#q-how-to-connect-to-different-tunnel-except-direct。
kafka通道中的数据是有控制信息在里面的,用户不好直接剥离,可以用receiver进行对接。目前receiver对接后所有oplog都打印到控制台,用户也可以自己修改receiver代码,对接下游服务。当然,这个需要用户懂golang语言,这可能有一些学习成本在里面。后面我们会看看如何以更好的形式对接给用户。

Q. 我发现mongoshake建立以后对源端性能有所影响,出现了一些慢查询。
A: 目前全量阶段由于是扫表等操作,会对源端产生一些影响。增量阶段,正常情况影响很小,因为目前oplog找对应ts是二分模式。

Q. 是否可以把一个MongoDB同步到多个MongoDB?
A: 可以,需要启动多个mongoshake。对于不同的mongoshake,可以修改写入不同地方的checkpoint即可(比如表名修改一下),或者直接修改不同的collector.id。此外,需要注意的是,同一个目录下启动多个mongoshake,如果collector.id相同,是无法启动成功的。参考:https://github.com/alibaba/MongoShake/wiki/FAQ#q-how-to-sync-data-from-one-mongodb-to-several-target-mongodb

Q&A说明参考博客:https://www.cnblogs.com/dh17/articles/14816662.html

好了,这就是MongoShake迁移同步mongo数据库的全部过程了,如有问题可与博主一起交流讨论!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值