首页 > 数据库 > NoSQL > Mongo数据迁移实验
公司现有线上mongo环境:
1. 不同版本(2.2.0、2.2.2、2.4.8、tokumx-2.0.0)
2. 不同架构环境(单实例、带master参数的单实例,分片+副本集)
为了将现有复杂的线上环境在不影响业务正常运行的条件下,迁移到同一套副本集环境中,下文模拟了不同版本、不同架构的情况下,来进行数据迁移到新的副本集(具体源环境见下节的源端环境)的实验
难点:由于源端是线上环境(随时数据会变化),在不影响业务正常使用(尽量不停机或者停机时间很短)的情况下迁移数据到新环境,同时要保证数据一致性、完整性
公司目前现有mongo环境,如下
|
业务 |
主机 |
版本 |
环境 |
分类 |
|
-- |
-- |
2.2.2 |
单--master |
2 |
|
-- |
-- |
2.2.0 |
单实例 |
1 |
|
-- |
-- |
2.2.2 |
分片+副本集 |
4 |
|
-- |
-- |
2.4.8 |
单--master |
3 |
|
-- |
-- |
tokumx-2.0.0 |
单 |
5 |
|
-- |
-- |
2.2.0 |
单实例 |
1 |
|
-- |
2.2.0 |
单实例 |
1 |
#如上环境分为5类,下面将模拟出相同版本和相同环境的mongodb实例,进行迁移实验
#3个node的副本集
yougou:PRIMARY> rs.status()
{
"set" : "yougou",
"date" : ISODate("2015-04-01T17:20:06Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.211.250:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1061,
"optime" : Timestamp(1427908775, 1),
"optimeDate" : ISODate("2015-04-01T17:19:35Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.211.250:20000",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 34,
"optime" : Timestamp(1427908775, 1),
"optimeDate" : ISODate("2015-04-01T17:19:35Z"),
"lastHeartbeat" : ISODate("2015-04-01T17:20:04Z"),
"lastHeartbeatRecv" : ISODate("2015-04-01T17:20:05Z"),
"pingMs" : 0,
"syncingTo" : "192.168.211.250:27017"
},
{
"_id" : 2,
"name" : "192.168.211.250:30000",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 31,
"optime" : Timestamp(1427908775, 1),
"optimeDate" : ISODate("2015-04-01T17:19:35Z"),
"lastHeartbeat" : ISODate("2015-04-01T17:20:05Z"),
"lastHeartbeatRecv" : ISODate("2015-04-01T17:20:05Z"),
"pingMs" : 0,
"syncingTo" : "192.168.211.250:27017"
}
],
"ok" : 1
}
mongosync 是 mongodb 数据同步工具,目前已支持绝大多种数据同步。
注意:
1. mongosync通过mongo的oplog来实现增量同步,故如果要实现实时同步,则源端必须打开oplog功能,而oplog只有在mong复制、副本集环境下才会打开。于是,对于没有指定—master参数的单实例,需要重启mongdb,指定—master选项来实现
2. mongosync使用需要指定用户密码,故源端如果没有存在admin用户,需要addUser
/data/mongod/mongodb-2.2.0/bin/mongod --dbpath /data/mongodb/node1 --logpath /data/mongodb/logs/mongodb-2.2.0.log --logappend --fork --auth --port 22000 –directoryperdb
如上,启动选项看出 无 master选项
~]# /data/mongod/mongodb-2.2.0/bin/mongo --port 22000
MongoDB shell version: 2.2.0
connecting to: 127.0.0.1:22000/test
> show dbs
admin (empty)
db220 0.203125GB
local (empty) #说明没有oplog
> use db220
switched to db db220
> show collections
system.indexes
t220
> db.t220.count()
888
~]# mongosync -h 192.168.211.217:22000 -u root -p yougou –d db220 --to 192.168.211.250:27017 -tu root -tp yougou --oplog
connected to: 192.168.211.217:22000
Thu Apr 2 01:57:07.632 [mongosync] 192.168.211.217:22000 connected ok
Thu Apr 2 01:57:07.634 [mongosync] admin auth ok
Thu Apr 2 01:57:07.635 [mongosync] 192.168.211.250:27017 connected ok
Thu Apr 2 01:57:07.636 [mongosync] admin auth ok
Thu Apr 2 01:57:07.639 [mongosync] lastOp OpTime:0,0 (Jan 1 08:00:00 0:0)
Thu Apr 2 01:57:07.639 [mongosync] clone all dbs ^_^
Thu Apr 2 01:57:07.641 [mongosync] DATABASE: db220 to db220
Thu Apr 2 01:57:07.910 [mongosync] cloning db220.t220 -> db220.t220
Thu Apr 2 01:57:07.927 [mongosync] 888 objects
Thu Apr 2 01:57:07.928 [mongosync] cloning db220.system.users -> db220.system.users
Thu Apr 2 01:57:07.930 [mongosync] 0 objects
Thu Apr 2 01:57:07.930 [mongosync] cloning db220.system.indexes -> db220.system.indexes
Thu Apr 2 01:57:07.932 [mongosync] 1 objects
Thu Apr 2 01:57:07.937 [mongosync] 0 objects
Thu Apr 2 01:57:07.940 [mongosync] clone done,start to catch up
Thu Apr 2 01:57:07.941 [mongosync] No new ops,waiting...
Thu Apr 2 01:57:12.942 [mongosync] No new ops,waiting...
……….
yougou:PRIMARY> db.t220.count()
888 #发现源端的db220同步完成
#源端修改数据(insert)
> for(var i=1;i<=888;i++) db.t220.save({"id":i,"a":123456789,"b":888888888,"c":100000000})
> db.t220.count()
1776
#目标端查看,新修改的数据没有同步
yougou:PRIMARY> db.t220.count()
888
故不能做到实时同步,为了解决此问题,则源端必须打开oplog,我们借助最简单的方式 指定—master选项启动
~]# netstat -ntpl|grep mongo|grep 22000
tcp 0 0 0.0.0.0:22000 0.0.0.0:* LISTEN 20696/mongod
]# kill 20696
--指定maste选项
]# /data/mongod/mongodb-2.2.0/bin/mongod --dbpath /data/mongodb/node1 --logpath /data/mongodb/logs/mongodb-2.2.0.log --logappend --fork --auth --port 22000 --directoryperdb –master
forked process: 5558
all output going to: /data/mongodb/logs/mongodb-2.2.0.log
child process started successfully, parent exiting
#登录源端,发现oplog已经打开
> use local
switched to db local
> show collections
oplog.$main
~]# mongosync -h 192.168.211.217:22000 -u root -p yougou -d db220 --to 192.168.211.250:27017 -tu root -tp yougou –oplog
Thu Apr 2 02:12:39.672 [mongosync] 192.168.211.217:22000 connected ok
Thu Apr 2 02:12:39.675 [mongosync] admin auth ok
Thu Apr 2 02:12:39.675 [mongosync] 192.168.211.250:27017 connected ok
Thu Apr 2 02:12:39.677 [mongosync] admin auth ok
Thu Apr 2 02:12:39.681 [mongosync] lastOp OpTime:1427941057,1 (Apr 2 10:17:37 551ca6c1:1)
Thu Apr 2 02:12:39.681 [mongosync] DATABASE: db220 to db220
Thu Apr 2 02:12:40.005 [mongosync] cloning db220.t220 -> db220.t220
Thu Apr 2 02:12:40.098 [mongosync] 1776 objects
Thu Apr 2 02:12:40.098 [mongosync] cloning db220.system.users -> db220.system.users
Thu Apr 2 02:12:40.102 [mongosync] 0 objects
Thu Apr 2 02:12:40.102 [mongosync] cloning db220.system.indexes -> db220.system.indexes
Thu Apr 2 02:12:40.106 [mongosync] 1 objects
Thu Apr 2 02:12:40.106 [mongosync] sync database: db220
Thu Apr 2 02:12:40.108 [mongosync] begin to apply oplog...
Thu Apr 2 02:12:40.108 [mongosync] db220:0 rows oplog to apply...
。。。。。。。。。。
#此时在源端新增加数据
> for(var i=1;i<=8888;i++) db.t220.save({"id":i,"a":123456789,"b":888888888,"c":100000000})
> db.t220.count()
10664
#目标端同步的日志可以发现,增量同步了
Thu Apr 2 02:13:06.158 [mongosync] No new oplogs,the data is the newest ^_^.waiting.
Thu Apr 2 02:13:07.175 [mongosync] Synced up to optime:ts: Timestamp 1427941089000|1
Thu Apr 2 02:13:12.650 [mongosync] 8888 ops
Thu Apr 2 02:13:12.650 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:16.403 [mongosync] 8888 ops
Thu Apr 2 02:13:16.403 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:21.415 [mongosync] 8888 ops
Thu Apr 2 02:13:21.415 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:25.420 [mongosync] 8888 ops
Thu Apr 2 02:13:25.420 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:30.432 [mongosync] 8888 ops
Thu Apr 2 02:13:30.432 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:34.435 [mongosync] 8888 ops
Thu Apr 2 02:13:34.435 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:39.447 [mongosync] 8888 ops
Thu Apr 2 02:13:39.448 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:44.297 [mongosync] 8888 ops
Thu Apr 2 02:13:44.297 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
Thu Apr 2 02:13:49.309 [mongosync] 8888 ops
Thu Apr 2 02:13:49.309 [mongosync] db220:8888 rows oplog are applied, waiting for new data ^_^.The latest optime is ts: Timestamp 1427941089000|8888
#同时登录目标端,可以看到表的记录在增加
yougou:PRIMARY> db.t220.count()
1776
yougou:PRIMARY> db.t220.count()
10664
同样在源端新创建集合也能实时同步,从而做到真正意义的同步
1. 重启源端单实例mongodb,启动的时候指定—master参数
2. 在目标端使用mongosync对-d xxx指定的数据库进行同步,指定—oplog可以做到实时同步
3. 同步跟上后,源端的上层应用可以切换到目标端
4. 待目标端使用确定没问题后,源端可以销毁
直接进行实时同步,同上面1的实时数据同步—master
~]# mongosync -h 192.168.211.217:22200 -u root -p yougou -d db222 --to 192.168.211.250:27017 -tu root -tp yougou --oplog
同上
~]# mongosync -h 192.168.211.217:24800 -u root -p yougou -d db248 --to 192.168.211.250:27017 -tu root -tp yougou –oplog
~]# mongosync -h 192.168.211.217:20000 -d yougou --to 192.168.211.250:27017 -tu root -tp yougou --oplog
connected to: 192.168.211.217:20000
Thu Apr 2 05:29:34.491 [mongosync] 192.168.211.217:20000 connected ok
Thu Apr 2 05:29:34.492 [mongosync] 192.168.211.250:27017 connected ok
Thu Apr 2 05:29:34.549 [mongosync] admin auth ok
Thu Apr 2 05:29:34.554 [mongosync] stop balancer
Thu Apr 2 05:29:34.557 [mongosync] target shards are less than source shards.
#由于mongosync暂时不支持分片同步到副本集,需要单独开多个mongosync分别连到各个分片来同步,有几个分片开几个mongosync,并且如果要实现实时同步,就必须用到oplog增量,所以源端的分片必须副本集或者主从(总之oplog开启)
~]# /data/mongod/mongodb-2.2.2/bin/mongo --port 20000
MongoDB shell version: 2.2.2
connecting to: 127.0.0.1:20000/test
mongos> use config
switched to db config
mongos> db.shards.find()
{ "_id" : "shard1", "host" : "shard1/192.168.211.217:30000,192.168.211.217:40000" }
{ "_id" : "shard2", "host" : "shard2/192.168.211.217:50000,192.168.211.217:60000" }
#如上,有2个分片shard1和shard2分别为2节点的副本集
mongos>for(var i=1;i<=888888;i++) db.yujx.save({"id":i,"a":123456789,"b":888888888,"c":100000000})
mongos>for(var i=1;i<=888888;i++) db.yujx.save({"id":0,"a":123456789,"b":888888888,"c":100000000})
#同步分片shard1的
~]# mongosync -h 192.168.211.217:30000 -d yougou --to 192.168.211.250:27017 -tu root -tp yougou –oplog
#同步分片shard2的
~]# mongosync -h 192.168.211.217:50000 -d yougou --to 192.168.211.250:27017 -tu root -tp yougou –oplog
#最终,源端查询yujx集合状态可知:shard1上28929 row,shard2上357412 row,共386341行
mongos> db.yujx.stats()
{
"sharded" : true,
"ns" : "yougou.yujx",
"count" : 386341,
"numExtents" : 13,
"size" : 26271188,
"storageSize" : 40591360,
"totalIndexSize" : 26326720,
"indexSizes" : {
"_id_" : 12558336,
"id_1" : 13768384
},
"avgObjSize" : 68,
"nindexes" : 2,
"nchunks" : 3,
"shards" : {
"shard1" : {
"ns" : "yougou.yujx",
"count" : 28929,
"size" : 1967172,
"avgObjSize" : 68,
"storageSize" : 2793472,
"numExtents" : 5,
"nindexes" : 2,
"lastExtentSize" : 2097152,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 1766016,
"indexSizes" : {
"_id_" : 948416,
"id_1" : 817600
},
"ok" : 1
},
"shard2" : {
"ns" : "yougou.yujx",
"count" : 357412,
"size" : 24304016,
"avgObjSize" : 68,
"storageSize" : 37797888,
"numExtents" : 8,
"indexSizes" : {
"_id_" : 11609920,
"id_1" : 12950784
},
"ok" : 1
}
},
"ok" : 1
}
mongos> db.yujx.count()
386341
#到目标端查询集合yujx的情况
yougou:PRIMARY> db.yujx.count()
386341
yougou:PRIMARY> db.yujx.stats()
{
"ns" : "yougou.yujx",
"count" : 386341,
"size" : 27816584,
"avgObjSize" : 72.00008282838218,
"storageSize" : 37797888,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 26948096,
"indexSizes" : {
"_id_" : 12541984,
"id_1" : 14406112
},
"ok" : 1
}#如上 源端和目标端的数据室同步的
并且 同步过程中mongosync通过日志,可以看到实时增量部分的情况,或者,在目标端隔时来运行db.yujx.count()可以看到,数据量一致增加的,从而做到了实时同步
mongosync的限制上写了,不适用于TokuMX同步数据到Mongo
故,此种情况为了保证数据完整性,必须给停机或者应用停止修改数据的时间窗口,在此期间导出数据 并且导入mongo完成后,应用直接连新的mongo环境
将如下源环境迁移到目标(副本集)环境
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/27000195/viewspace-1521573/ ,如需转载,请注明出处,否则将追究法律责任。