用mongoshake实现mongo分片集群到单实例和分片集群的数据同步

Posted 雅冰石

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用mongoshake实现mongo分片集群到单实例和分片集群的数据同步相关的知识,希望对你有一定的参考价值。

一 实验环境

 这里演示只同步源端ccc库下的t1,t2表,ddd库下的所有表到两个目标端。

二 实验步骤

2.1 创建专用账号

2.1.1 在源端创建账号

2.1.1.1 登录其中一个mongos节点创建用户

#这里创建一个mongoshake用户,密码是123456

use admin;

db.createUser(user:"mongoshake",pwd:"123456",roles:[role:"readWrite",db:"admin"]);

db.grantRolesToUser("mongoshake",[role:"read",db:"local"])

db.grantRolesToUser("mongoshake",[role:"readWrite",db:"mongoshake"]);

2.1.1.2 在每个分片主节点上创建用户

use admin;

db.createUser(user:"mongoshake",pwd:"123456",roles:[role:"readWrite",db:"admin"]);

db.grantRolesToUser("mongoshake",[role:"read",db:"local"])

db.grantRolesToUser("mongoshake",[role:"clusterMonitor",db:"admin"])

2.1.2 在目标端创建账号

2.1.2.1 登录其中一个mongos节点创建用户

#登录mongos节点,创建一个对所有库都具有读写权限的账号

use admin;

db.createUser(user:"mongoshake",pwd:"123456",roles:[role:"readWriteAnyDatabase",db:"admin"]);

2.2 关闭分片集群的balancer

对于sharding的同步,需要关掉balancer进行同步,否则会有时序不一致的问题。

暂不支持move chunk的同时进行同步。

#登录其中一台mongos服务器执行

mongos> sh.getBalancerState()

true

mongos> sh.stopBalancer()

"ok" : 1,

"operationTime" : Timestamp(1640785850, 4),

"$clusterTime" :

"clusterTime" : Timestamp(1640785850, 4),

"signature" :

"hash" : BinData(0,"1YhPvOALc/9ggQN+E3+GfTDjcKs="),

"keyId" : NumberLong("7046829662332256286")

mongos> sh.getBalancerState()

false

2.3 安装mongoshake

#在所有目标端都安装下mongoshake(若目标端是mongo分片集群,则只在分片集群其中一台服务器上安装即可)

Mongo shake下载地址:

https://github.com/alibaba/MongoShake/releases?spm=a2c6h.12873639.0.0.695e4a3dr8l0Ee

cd /opt

tar -xvf mongo-shake-v2.4.16.tar.gz

mv mongo-shake-v2.4.16 mongoshake

cd mongoshake

2.4 配置mongoshake

2.4.1 目标端为单实例的情形

#这里以往目标端192.168.144.252同步为例

vi collector.conf

# 配置MongoDB连接串信息,逗号分隔同一个副本集内的点,分号分隔分片sharding实例

mongo_urls = mongodb://mongoshake:123456@192.168.144.249:27021,192.168.144.250:27021,192.168.144.251:27021;mongodb://mongoshake:123456@192.168.144.249:27022,192.168.144.250:27022,192.168.144.251:27022;mongodb://mongoshake:123456@192.168.144.249:27023,192.168.144.250:27023,192.168.144.251:27023

# 如果源端是分片集群,mongo_cs_url这里需要指定config服务器的地址

mongo_cs_url = mongodb://mongoshake:123456@192.168.144.249:27020,192.168.144.250:27020,192.168.144.251:27020

# 配置mongos的地址,多个mongos地址以逗号分割

mongo_s_url = mongodb://mongoshake:123456@192.168.144.249:27017,192.168.144.250:27017,192.168.144.251:27017

# 配置同步模式为全量+增量模式

sync_mode = all

# 这里配置只同步ccc.t1,ccc.t2,ddd库下的所有表,请结合自己业务情况进行设置,若想同步所有库的所有表,则不需要设置此选项,按默认即可。

filter.namespace.white = ccc.t1;ccc.t2;ddd

#配置目标端地址

tunnel.address = mongodb://mongoshake:123456@192.168.144.252:27017

#设置只同步某些对象,分号分割不同namespace,每个namespace可以是db,也可以是db.collection。

checkpoint.storage.collection = ckpt_default_1

2.4.2 目标端为分片集群的情形

mongo_urlsmongo_cs_url,mongo_s_url,sync_mode,filter.namespace.white等配置同2.4.1。但是tennel.address及checkpoint.storage.collection配置的时候需要注意:

#tennel.address设置为目标端的mongos地址

tunnel.address = mongodb://mongoshake:123456@192.168.144.231:27017,192.168.144.232:27017,192.168.144.233:27017

/*

注意:这里是用逗号分隔的,不是分号,否则会报错:

[2021/12/30 22:33:10 CST] [CRIT] Replayer-1, executor-1, oplog for namespace[ddd.y3] op[i] failed. error type[*mgo.BulkError] error[index[0], msg[command insert requires authentication], dup[false]], logs number[1], firstLog: "ts":7047498676503052294,"h":8608176140228710902,"v":2,"op":"i","ns":"ddd.y3","o":["Name":"_id","Value":"61cdbeb57912ca48bcaaa346","Name":"name","Value":444],"o2":null

*/

#注意:不同mongoshake里的checkpoint.storage.collection值应该是唯一的,不能和其他的重复,示例:

checkpoint.storage.collection = ckpt_default_2

2.5 启动mongoshake

sh start.sh collector.conf

#检查是否能看到collector进程

ps -ef |grep collector | grep -v 'grep'

root     27759     1  0 18:52 ?        00:00:00 ./hypervisor --daemon --exec=./collector.linux -conf=collector.conf 1>> collector.linux.output 2>&1

root     27760 27759  0 18:52 ?        00:00:04 ./collector.linux -conf=collector.conf 1>> collector.linux.output 2>&1

/*

对应的停止命令是sh stop.sh mongoshake.pid。

日志文件路径:mongoshake/logs

有时启动mongoshake没起来,日志里也没报错,可用如下方式启动,能在启动页面就能看到有日志输出:

./collector.linux -conf=collector.conf -verbose

*/

2.6 验证数据同步

登录源端mongos,插入一条测试数据:

mongos> use ddd;

switched to db ddd

mongos> db.t1.insert("id":1,name:"baidd")

WriteResult( "nInserted" : 1 )

#在目标端查看数据是否能收到:

> use ddd;

switched to db ddd

> db.t1.find();

"_id" : ObjectId("61cb6590a2d018cc73dee5d3"), "id" : 1, "name" : "baidd"

发现数据过来了。

注意:

本篇文章没有开启ddl同步,若想开启ddl同步,则需要设置filter.ddl_enable = true。

若要设置该参数,还需要设置incr_sync.mongo_fetch_method = change_stream,否则会报错。但是实验的该mongoshake版本只支持部分ddl(库表的建/删,重命名),由于MongoDB本身的限制,对于建/删索引,convertToCapped,applyOps等都不支持。因此,本篇文章并未开启ddl同步。

本篇文章参考了:

https://github.com/alibaba/MongoShake/wiki/%E7%AC%AC%E4%B8%80%E6%AC%A1%E4%BD%BF%E7%94%A8%EF%BC%8C%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE%EF%BC%9F

MongoShake最佳实践-阿里云开发者社区

以上是关于用mongoshake实现mongo分片集群到单实例和分片集群的数据同步的主要内容,如果未能解决你的问题,请参考以下文章

用mongoshake实现mongo分片集群到单实例和分片集群的数据同步

k8s版MongoShake数据迁移工具

使用mongo shake实现从一个单实例mongo往多个mongo单实例进行数据同步

使用mongo shake实现从一个单实例mongo往多个mongo单实例进行数据同步

mongo 3.4分片集群系列之四:搭建分片集群--哈希分片 + 安全 + 区域

mongo 3.4分片集群系列之八:分片管理