ITPub博客

首页 > 数据库 > NoSQL > Mongo数据迁移实验

Mongo数据迁移实验

原创 NoSQL 作者:jx_yu 时间:2015-04-07 14:54:31 1 删除 编辑

说明

         公司现有线上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

mongosync 是 mongodb 数据同步工具,目前已支持绝大多种数据同步。

clip_image002

注意:

1.   mongosync通过mongo的oplog来实现增量同步,故如果要实现实时同步,则源端必须打开oplog功能,而oplog只有在mong复制、副本集环境下才会打开。于是,对于没有指定—master参数的单实例,需要重启mongdb,指定—master选项来实现

2.   mongosync使用需要指定用户密码,故源端如果没有存在admin用户,需要addUser

实验内容

1.mongo-2.2.0单实例无master选项迁移到副本集

非实时同步-直接迁移

源端环境

/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选项启动

实时数据同步—master

1.重启源端mongo实例

~]# 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

2.目标端执行同步命令

~]# 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

同样在源端新创建集合也能实时同步,从而做到真正意义的同步

3.主要操作步骤

1.       重启源端单实例mongodb,启动的时候指定—master参数

2.       在目标端使用mongosync对-d xxx指定的数据库进行同步,指定—oplog可以做到实时同步

3.       同步跟上后,源端的上层应用可以切换到目标端

4.       待目标端使用确定没问题后,源端可以销毁

2.mongo-2.2.2并且有master选项迁移到副本集

直接进行实时同步,同上面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

3.mongo-2.4.8并且有master选项迁移到副本集

同上

~]# mongosync -h 192.168.211.217:24800 -u root -p yougou -d db248 --to 192.168.211.250:27017  -tu root -tp yougou –oplog

4.分片(副本集)同步到副本集

~]# 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})

目标端开启mongosync同步

#同步分片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()可以看到,数据量一致增加的,从而做到了实时同步

5.tokumx-2.0.0同步到mongo副本集

mongosync的限制上写了,不适用于TokuMX同步数据到Mongo

clip_image004

故,此种情况为了保证数据完整性,必须给停机或者应用停止修改数据的时间窗口,在此期间导出数据 并且导入mongo完成后,应用直接连新的mongo环境

实验结果

将如下源环境迁移到目标(副本集)环境

clip_image006

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/27000195/viewspace-1521573/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-05-23

  • 博文量
    80
  • 访问量
    876947