mongo上云迁移同步mongoshake
关于MongoShake项目说明:https://github.com/alibaba/MongoShake/wikiMongoShake发行版下载:https://github.com/alibaba/MongoShake/releasesMongoShake遇到的问题FAQ:https://github.com/alibaba/MongoShake/wiki/FAQ...
关于MongoShake项目说明:
https://github.com/alibaba/MongoShake/wiki
MongoShake发行版下载:
https://github.com/alibaba/MongoShake/releases
MongoShake遇到的问题FAQ:
https://github.com/alibaba/MongoShake/wiki/FAQ
- 安装
项目相关软件包路径为/root/MongoShake,部署之前确保目标端实例已使用源端实例全备mongodump文件进行还原,MongoShake是通过抽取源端oplog应用到目标端以达到增量的同步,利用的是oplog中DML操作的幂等特性,部署项目需要用到的组件有:
1.go go1.12.5(二进制)
2.MongoShake 2.0(源码包)或MongoShake 2.0(二进制)
go的安装
MongoShake是基于go语言进行开发的,在进行源码编译的时候需要go的运行环境。本例的go语言环境配置使用的是二进制包方式。如果使用的MongoShake二进制包,解压即可得到MongoShake执行命令,则无需要安装go环境。
- 二进制包下载
# wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
- 解压
# tar zxf go1.12.5.linux-amd64.tar.gz
# cp go /usr/local/go1.12 –ra
- 配置环境变量
# vim /etc/profile.d/go.sh
添加配置:
export GOROOT=/usr/local/go1.12
export GOPATH=/go
export PATH=/go/bin:$GOROOT/bin:$PATH
配置生效:
# . /etc/profile.d/go.sh
- 查看当前go环境
# go version
go version go1.12.5 linux/amd64
至此,go语言环境安装完成。
MongoShake的安装(源码)
因为MongoShake的项目源码是放在github上的,所以获取源码的方式可以通过git进行,也可以到项目地址下载zip源码压缩包。
- Git安装
首先确保安装了git,如果没有安装则使用yum进行安装。
# git version
git version 2.21.0
yum安装git:
# yum install git -y
- 源码包获取
因为国内环境访问github的速度较慢,所以可以先修改hosts文件,通过绑定host的方式来访问,可以加快对github访问的速度。
# vim /etc/hosts
文末添加:
151.101.44.249 github.global.ssl.fastly.net
192.30.253.113 github.com
103.245.222.133 assets-cdn.github.com
23.235.47.133 assets-cdn.github.com
203.208.39.104 assets-cdn.github.com
204.232.175.78 documentcloud.github.com
204.232.175.94 gist.github.com
107.21.116.220 help.github.com
207.97.227.252 nodeload.github.com
199.27.76.130 raw.github.com
107.22.3.110 status.github.com
204.232.175.78 training.github.com
207.97.227.243 www.github.com
185.31.16.184 github.global.ssl.fastly.net
185.31.18.133 avatars0.githubusercontent.com
185.31.19.133 avatars1.githubusercontent.com
192.30.253.120 codeload.github.com
注意每行行尾不能出现空格,否则绑定的host不生效!
获取源代码:
# mkdir /go/src/github.com/
# cd /go/src/github.com/
# git clone https://github.com/alibaba/MongoShake.git
Cloning into 'MongoShake'...
remote: Enumerating objects: 60, done.
remote: Counting objects: 100% (60/60), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 1341 (delta 14), reused 29 (delta 10), pack-reused 1281
Receiving objects: 100% (1341/1341), 18.56 MiB | 24.00 KiB/s, done.
Resolving deltas: 100% (694/694), done.
- 依赖包安装
MongoShake使用的是govendor解决依赖包问题,在编译MongoShake之前需要确认依赖包都已安装,而首先安装的是govendor。
# go get -u github.com/kardianos/govendor
# govendor -version
v1.0.9
govendor安装完成之后,开始安装MongoShake的依赖包。
# GOPATH= /go/src/github.com/MongoShake/
# cd /go/src/github.com/MongoShake/src/vendor
# govendor sync
- 编译
依赖包安装完成之后,则可以开始进行编译了。
# cd /go/src/github.com/MongoShake/
# ./build.sh
[ BUILD RELEASE ]
Build collector
mongoshake/collector/configure
vendor/github.com/eapache/queue
vendor/github.com/vinllen/log4go
vendor/github.com/gugemichael/nimo4go
vendor/github.com/vinllen/mgo/internal/json
vendor/github.com/vinllen/mgo/internal/scram
vendor/github.com/nightlyone/lockfile
vendor/github.com/davecgh/go-spew/spew
vendor/github.com/eapache/go-resiliency/breaker
vendor/github.com/golang/snappy
vendor/github.com/vinllen/mgo/bson
vendor/github.com/eapache/go-xerial-snappy
vendor/github.com/pierrec/lz4/internal/xxh32
vendor/github.com/pierrec/lz4
vendor/github.com/rcrowley/go-metrics
vendor/github.com/vinllen/mgo
mongoshake/oplog
vendor/github.com/Shopify/sarama
mongoshake/common
mongoshake/dbpool
mongoshake/collector/ckpt
mongoshake/executor
mongoshake/quorum
mongoshake/tunnel/kafka
mongoshake/tunnel
mongoshake/modules
mongoshake/collector
command-line-arguments
develop,7858a69529c89b04207a9913df7ac0e082b256af,release,go1.12.5,2019-06-19_13:19:39
Build receiver
mongoshake/receiver/configure
mongoshake/receiver
command-line-arguments
develop,7858a69529c89b04207a9913df7ac0e082b256af,release,go1.12.5,2019-06-19_13:19:39
至此,MongoShake编译完成。
MongoShake的安装(二进制)
因为获取依赖包访问github的速度很慢,所以项目也提供了编译好的二进制包,二进制包会使用相对比较稳定的源码进行编译,如果允许的话还是使用源码包进行编译。
- 二进制下载
# wget https://github.com/alibaba/MongoShake/releases/download/release-v2.0.0-20190619/mongoshake-2.0.tar.gz
- 解压
# tar zxf mongoshake-2.0.tar.gz -C /go/src/github.com/MongoShake-2.0
# ls /go/src/github.com/MongoShake-2.0/
ChangeLog collector collector.conf hypervisor mongoshake-stat receiver start.sh stop.sh
至此,MongoShake的配置就完成了。
- 配置
MongoShake同步任务配置根据原先项目的设计做了自定义配置,采用每个项目对应一个目录的方式进行,这样可以方便管理与维护,可以参考已成功完成迁移的实例bbs进行修改,本例以bbs配置进行修改演示,由于之前bbs项目是基于MongoShake 1.4.6版本完成的,collector配置文件与2.0稍有不同,可以参照2.0版本进行修改。
查看bbs对应目录结构
# tree /go/src/github.com/MongoShake/bbs/ -L 1
/go/src/github.com/MongoShake/bbs/
├── bbs_collector
├── bbs.conf
├── bbs_start.sh
├── bbs_stop.sh
├── diagnostic
└── logs
其中:
bbs_collector:MongoShake拉取oplog的主执行程序,通过默认collector复制重命名得到;
bbs.conf:MongoShake配置文件,针对bbs的配置;
bbs_start.sh:项目启动的shell脚本,结合默认的hypervisor启动项目;
bbs_stop.sh:项目停止的shell脚本;
logs:存放hypervisor日志和bbs_collector运行日志。
配置项目目录
本例以ask项目为例。
# mkdir -pv /go/src/github.com/MongoShake-2.0/ask/logs
# cd /go/src/github.com/MongoShake-2.0/ask
拷贝BBS相应的文件,并重命名。
# cp ../../MongoShake/bbs/bbs* /go/src/github.com/MongoShake-2.0/ask
# mv bbs_collector ask_collector
# mv bbs.conf ask.conf
# mv bbs_start.sh ask_start.sh
# mv bbs_stop.sh ask_stop.sh
配置文件修改
修改ask.conf配置文件,也可以基于MongoShake 2.0版本默认的配置文件进行修改。
为了便于说明,先去除相应的注释与空行。
# cat ask.conf | grep -v "^$" | grep -v "^#"
mongo_urls = mongodb://root:sdfsdfsdf@10.10.111.1:27018,10.10.111.2:27230 #源端
collector.id = askSet
sync_mode = oplog
checkpoint.interval = 5000
http_profile = 20230
system_profile = 20231
log_level = info
log_file = askSet.log
log_buffer = true
filter.namespace.black =
filter.namespace.white =
oplog.gids =
shard_key = collection
syncer.reader.buffer_time = 1
worker = 1
worker.batch_queue_size = 32
adaptive.batching_max_size = 8192
fetcher.buffer_capacity = 128
worker.oplog_compressor = none
tunnel = direct
tunnel.address = mongodb://root:csdfsdfsdfsd@172.20.16.1:27017 #目标端
context.storage = database
context.address = ckpt_default
context.start_position = 2019-06-18T09:20:00Z
master_quorum = false
transform.namespace =
dbref = false
replayer.dml_only = false
replayer.executor = 1
replayer.executor.upsert = true
replayer.executor.insert_on_dup_update = true
replayer.conflict_write_to = none
replayer.durable = true
replayer.collection_parallel = 3
replayer.document_parallel = 4
replayer.document_batch_size = 256
replayer.collection_drop = false
主要配置选项如下:
mongo_urls:配置源端实例mongodb连接信息,如果是副本集,将所有mongodb节点都写上,格式如上;
collector.id:项目进程名称,能唯一标识即可;
sync_mode:同步模式,2.0开始支持全量+增量,默认为oplog,即增量,对于一些较小的实例可以采用all方式;
http_profile:项目进程监控端口,确保唯一即可;
system_profile:项目进程监控端口,确保唯一即可;
log_file:collector日志文件名称,会在logs目录下生成;
tunnel.address:目标端mongodb实例连接信息,格式如上;
context.start_position:开始读取oplog的时间点,是UTC格式,比CST晚8小时,即开始同步时间需要比生成mongodump全备文件早8个小时开始同步,才能确保在oplog增量同步时覆盖mongodump备份这段时间的操作;
replayer.dml_only:是否只同步DML,如果需要同步DDL,则指定选项false。
配置文件其他选项保持默认就可以。
启动文件修改
修改ask_start.sh文件。
# vim ask_start.sh
#catalog=$(dirname "$0")
#cd "${catalog}"/../ || exit 1
if [ $# != 1 ] ; then
echo "USAGE: $0 [conf]"
exit 0
fi
# conf
hypervisor_path="/go/src/github.com/MongoShake-2.0/hypervisor"
collector_path="/go/src/github.com/ MongoShake-2.0/ask/ask_collector"
conf_path="/go/src/github.com/ MongoShake-2.0/ask/ask.conf"
logs_dir="/go/src/github.com/ MongoShake-2.0/ask/logs/"
task_name="askSet_collector"
if [ "Darwin" == "$(uname -s)" ];then
printf "\\nWARNING !!! MacOs doesn't supply to use this script, please use \"./%s -conf=config_file_name\" manual command to run\\n" "$nam
e"
exit 1
fi
GOMAXPROCS=0
if [ $GOMAXPROCS != 0 ] ; then
${hypervisor_path} --daemon --exec="GOMAXPROCS=$GOMAXPROCS ${collector_path} -conf=$1 2>&1 1>> $task_name.output" 1>>${logs_dir}hypervisor
.output 2>&1
else
${hypervisor_path} --daemon --exec="${collector_path} -conf=$1 2>&1 1>> $task_name.output" 1>>${logs_dir}hypervisor.output 2>&1
Fi
其中涉及修改的选项如下,配置参考以上说明:
hypervisor_path:hypervisor路径,以项目默认为主;
collector_path=:ask对应的collector执行文件;
conf_path=:ask对应的配置文件;
logs_dir=:ask对应的日志文件路径;
task_name=:ask任务名称。
至此,ask项目配置已完成。
- 开启同步
本例中ask项目源端开始mongodump生成全备文件时的时间为:
2019-06-18T17:24:25.699+0800
所以ask配置的oplog同步时间为:
2019-06-18T09:20:00Z
在确保ask mongodump全备文件通过mongorestore还原至目标端实例成功完成之后,使用shell启动文件开始进行同步。
# cd /go/src/github.com/ MongoShake-2.0/ask/
# ./ask_start.sh ask.conf
查看ask_collector日志状态。
[2019/06/19 15:35:22 CST] [INFO] [common.(*ReplicationMetric).startup.func1:137] [name=askReplset, filter=2, get=211, consume=209, apply=209, failed_times=0, success=209, tps=0, ckpt_times=0, retransimit_times=0, tunnel_traffic=29KB, lsn_ckpt={0,1970-01-01 08:00:00}, lsn_ack={1560929701,2019-06-19 15:35:01}]
[2019/06/19 15:35:23 CST] [INFO] [collector.(*OplogSyncer).calculateWorkerLowestCheckpoint:122] worker offset [6704142017150058497] use lowest 6704142017150058497
[2019/06/19 15:35:23 CST] [INFO] [executor.(*Executor).doSync:231] Replayer-0 Executor-0 doSync oplogRecords received[1] merged[1]. merge to 100.00% chunks
[2019/06/19 15:35:23 CST] [INFO] [collector.(*Worker).transfer:179] Collector-worker-0 transfer retransmit:false send [1] logs. reply_acked [6704142107344371713], list_unack [0]
[2019/06/19 15:35:23 CST] [INFO] [ckpt.(*MongoCheckpoint).Insert:179] Record new checkpoint success [1560929701]
[2019/06/19 15:35:23 CST] [INFO] [collector.(*OplogSyncer).checkpoint:54] CheckpointOperation write success. updated from 6704125962562306050(1560925963) to 6704142017150058497(1560929701)
[2019/06/19 15:35:27 CST] [INFO] [common.(*ReplicationMetric).startup.func1:137] [name=askReplset, filter=3, get=213, consume=210, apply=210, failed_times=0, success=210, tps=0, ckpt_times=1, retransimit_times=0, tunnel_traffic=29KB, lsn_ckpt={1560929701,2019-06-19 15:35:01}, lsn_ack={1560929722,2019-06-19 15:35:22}]
[2019/06/19 15:35:30 CST] [INFO] [collector.(*OplogSyncer).calculateWorkerLowestCheckpoint:122] worker offset [6704142107344371713] use lowest 6704142107344371713
[2019/06/19 15:35:30 CST] [INFO] [executor.(*Executor).doSync:231] Replayer-0 Executor-0 doSync oplogRecords received[1] merged[1]. merge to 100.00% chunks
查看运行监控端口状态。
# netstat -lntup | grep ask
tcp6 0 0 :::20231 :::* LISTEN 5312/ask_collector
tcp6 0 0 :::20230 :::* LISTEN 5312/ask_collector
从collector日志可以看出实时的oplog增量检查点checkpoint,而这个checkpoint信息由MongoShake默认创建mongoshake数据库和ckpt_default集合来记录,记录的是当前增量同步oplog位置的时间信息。
cmsReplset:SECONDARY> db.ckpt_default.find()
{ "_id" : ObjectId("5d09f22ccee40923c7e59a50"), "name" : "cmsReplset", "ckpt" : Timestamp(1560931886, 3) }
- 停止同步
使用ask_stop.sh文件停止ask项目的同步。
# ./ask_stop.sh askSet.pid
- 数据量校验
为了校验MongoDB同步后各个数据库中集合文档数,这里编写了一个shell脚本mongodb_compare.sh,脚本已同步到DBA SVN中迁移百度云文件夹下,使用方法可以通过直接运行脚本文件得到。
# ./mongodb_compare.sh
USAGE:./mongodb_compare.sh 'src_MongoDB_Primary_ip:port' 'dst_MongoDB_Primary_ip:port' [db_name for check...]
Example: ./mongodb_compare.sh '192.168.58.3:27017' '172.20.3.6:27017' [db_name,[db_name]...]
这里演示校验ask实例源端和目标端集合文档数。
首先需确认当前mongoshell执行命令mongo的绝对路径,并修改脚本中涉及mongo命令的地方,假设当前mongo命令的绝对路径为/usr/local/mongodb3.4/bin/mongo,则修改mongodb_compare.sh脚本中涉及mongo命令处,并保存。如下:
src_conn="/usr/local/mongodb3.4/bin/mongo $src_ins -u$src_user -p$src_pwd --quiet --authenticationDatabase admin -eval "
dst_conn="/usr/local/mongodb3.4/bin/mongo $dst_ins -u$dst_user -p$dst_pwd --quiet --authenticationDatabase admin -eval "
运行脚本进行校检。(脚本见下一篇推文)
# ./mongodb_compare.sh '10.10.111.1:27017' '172.20.16.1:27017'
Enter the src_ins:10.10.111.1:27017 conn user: root # 输入源端实例连接用户
Enter the src_ins:10.10.111.1:27017 user password: # 输入源端实例连接用户密码
Enter the dst_ins:172.20.16.1:27017 conn user: root # 输入目标端实例连接用户
Enter the dst_ins:172.20.16.1:27017 password: # 输入目标端实例连接用户密码
10.10.111.1:27017 <----------> 172.20.16.1:27017
==============================================================
DB:cms
autoincre_system docs: 3 <----------> 3
cms_mall_product docs: 3824 <----------> 3824
pageslog docs: 58043 <----------> 58043
pageslog_list docs: 58043 <----------> 58043
system.indexes docs: 7 <----------> 0 different!
system.profile docs: 1701 <----------> 0 different!
system.users docs: 2 <----------> 2
test docs: 1 <----------> 1
==============================================================
DB:test
system.indexes docs: 2 <----------> 0 different!
system.profile docs: 0 <----------> 0
t docs: 3 <----------> 3
test docs: 1 <----------> 1
==============================================================
DB:OpenPlatform
a docs: 0 <----------> 0
app_log_10 docs: 450904 <----------> 450904
app_log_11 docs: 406611 <----------> 406611
app_log_12 docs: 160810 <----------> 160810
app_log_5 docs: 1324893 <----------> 1324893
app_log_6 docs: 965174 <----------> 965174
app_log_7 docs: 855134 <----------> 855134
app_log_8 docs: 715728 <----------> 715728
app_log_9 docs: 639511 <----------> 639511
auth_info docs: 247083 <----------> 247083
feedback docs: 49 <----------> 49
qdms docs: 0 <----------> 0
system.indexes docs: 13 <----------> 0 different!
system.profile docs: 1748 <----------> 0 different!
user_session docs: 24200 <----------> 24200
如果有文档数不同的集合则脚本通过红色显示,如果只是system集合红色显示,代表正常,因为system集合是不做同步的,所以其他集合出现红色时则证明两端集合的文档数不一致。在确保源端与目标端实例除system集合外所有集合的文档数一致后则表明数据一致。
当源端集合文档数与目标端不一致时,则以源端数据为主进行修复。主要修复步骤:
- 首先停止MongoShake对应项目的同步;
- 源端使用mongodump导出不一致的文档;
- 目标端通过mongorestore还原不一致的文档;
- 重新开启MongoShake对应项目的同步。
导出文档命令:
# mongodump -h 10.10.111.1 --port 28230 -uroot –p’root_password’ --authenticationDatabase admin –d cms –c pageslog –o ./cms_pageslog
导入文档命令:
# mongorestore -h 172.20.16.1 --port 27017 -uroot -p’root_password’ --authenticationDatabase admin -d cms -c pageslog --drop ./pageslog.bson
- 用户迁移
如果源实例的admin数据库包含名为root的用户,并且该root用户为实例对应的拥有root角色超级权限的用户,则在使用mongorestore进行还原恢复至百度云mongodb实例时不能包括admin数据库,这会导致百度云实例上超级用户被修改,导致百度云后台技术错误,所以关于用户的迁移只能通过查找数据库连接配置文件对应项目中实例的连接用户,然后在百度云实例上admin或者相应数据库手动创建用户。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)