关于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环境。

 

  1. 二进制包下载

# wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz

 

  1. 解压

# tar zxf go1.12.5.linux-amd64.tar.gz

# cp go /usr/local/go1.12 –ra

 

  1. 配置环境变量

# 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

 

  1. 查看当前go环境

# go version

go version go1.12.5 linux/amd64

至此,go语言环境安装完成。

 

MongoShake的安装(源码)

因为MongoShake的项目源码是放在github上的,所以获取源码的方式可以通过git进行,也可以到项目地址下载zip源码压缩包。

 

  1. Git安装

首先确保安装了git,如果没有安装则使用yum进行安装。

 

# git version

git version 2.21.0

 

yum安装git:

# yum install git -y

 

  1. 源码包获取

因为国内环境访问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.

 

  1. 依赖包安装

 

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

 

  1. 编译

 

依赖包安装完成之后,则可以开始进行编译了。

 

# 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的速度很慢,所以项目也提供了编译好的二进制包,二进制包会使用相对比较稳定的源码进行编译,如果允许的话还是使用源码包进行编译。

 

  1. 二进制下载

# wget https://github.com/alibaba/MongoShake/releases/download/release-v2.0.0-20190619/mongoshake-2.0.tar.gz

 

  1. 解压

# 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集合外所有集合的文档数一致后则表明数据一致。

 

当源端集合文档数与目标端不一致时,则以源端数据为主进行修复。主要修复步骤:

 

  1. 首先停止MongoShake对应项目的同步;
  2. 源端使用mongodump导出不一致的文档;
  3. 目标端通过mongorestore还原不一致的文档;
  4. 重新开启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或者相应数据库手动创建用户。

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐