• MongoShake数据灾备与迁移


    安装部署

    解压

    建议部署在离目标端近的地方,比如部署再目标端本地

    tar -zxvf mongo-shake-v2.8.1.tgz
    
    • 1

    配置

    同构环境下主要参数
    在这里插入图片描述

    启动

    执行下述命令启动同步任务,并打印日志信息,-verbose 0表示将日志打印到文件,在后台运行

    nohup ./collector.linux -conf=collector.conf -verbose 0 &
    
    • 1

    全量

    为防止主库oplog不足,提前调整oplog大小

    db.adminCommand({replSetResizeOplog:1,size:1000})
    
    • 1

    观察打印日志信息,如下表示全量完成
    10GB数据限速8000TPS,耗时1.5H

    [09:38:57 CST 2019/06/20] [INFO] (mongoshake/collector.(*ReplicationCoordinator).Run:80) finish full sync, start incr sync with timestamp: fullBeginTs[1560994443], fullFinishTs[1560994737]
    
    • 1

    重新全量同步
    如需重新进行全量同步,只需要停止同步进程,删除存储checkpoint的表,重新启动同步进程即可

    use mongoshake
    db.ckpt_default.drop()
    
    • 1
    • 2

    问题

    全量同步时,报如下错误,源端环境为3.6.3,存在bug,通过小版本升级至3.6.23解决该问题
    bug连接:https://jira.mongodb.org/browse/SERVER-34810

    [2022/11/26 17:47:46 CST] [CRIT] splitter reader[DocumentReader id[0], src[mongodb://admin:***@192.168.62.25:27017,192.168.62.26:27017,192.168.62.27:27017] ns[{paymentdb test}] query[map[]]] get next document failed: (CursorNotFound) cursor id 75188853290 not found
    
    • 1

    如果还有什么问题可以直接到入下网址向作者反应
    https://github.com/alibaba/MongoShake/issues

    如何监控和管理MongoShake的运行状态?

    MongoDB一共从2个方面提供监控,全量和增量,分为2个端口。全量部分的监控是从2.4.1版本才开放的,增量部分监控从1.0.0就开放了。
    注意:通过sentinel接口的相应修改都不会持久化,也就是说通过sentinel接口修改的变量在MongoShake发生重启后都会清空,需要重新配置。持久化功能后面版本会做掉,敬请期待。

    如何查看监控?

    直接curl对应的端口就行,例如,在配置文件中有一个端口的配置,v2.4.1版本以前是http_profile(默认值是9100),v2.4.1开始分拆为2个,full_sync.http_port(默认9101)表示全量的端口,incr_sync.http_port(默认9100)是增量的端口。直接调用curl命令就能看到(加上python -m json可以更加清晰):

    vinllen@~/code/MongoShake$ curl -s  http://127.0.0.1:9101
    [{"Uri":"/conf","Method":"GET"},{"Uri":"/progress","Method":"GET"},...]
    vinllen@~/code/MongoShake$ curl -s  http://127.0.0.1:9101 | python -m json.tool
    [
        {
            "Method": "GET",
            "Uri": "/conf"
        },
        {
            "Method": "GET",
            "Uri": "/progress"
        }
        .... // 省略
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上面返回的有conf和progress,可以分别再curl这个对应的接口,比如conf表示的是配置文件信息:

    vinllen@~/code/MongoShake$ curl -s  http://127.0.0.1:9101/conf | python -m json.tool
    {
        "CheckpointInterval": 5000,
        "CheckpointStartPosition": 1585220856,
        "CheckpointStorage": "database",
        "CheckpointStorageCollection": "ckpt_default",
        "CheckpointStorageDb": "mongoshake",
        "CheckpointStorageUrl": "mongodb://xxx:31773,xxx:31772,xxx:31771",
        "ConfVersion": 1,
        "FilterDDLEnable": false,
        "FilterNamespaceBlack": null,
        "FilterNamespaceWhite": null,
        "FilterPassSpecialDb": [],
        "FullSyncCollectionDrop": true,
        "FullSyncCreateIndex": "foreground",
        "FullSyncExecutorDebug": false,
        "FullSyncExecutorFilterOrphanDocument": false,
        "FullSyncExecutorInsertOnDupUpdate": false,
        "FullSyncExecutorMajorityEnable": false,
        "FullSyncHTTPListenPort": 9100,
        "FullSyncReaderCollectionParallel": 6,
        "FullSyncReaderDocumentBatchSize": 128,
        "FullSyncReaderOplogStoreDisk": false,
        "FullSyncReaderOplogStoreDiskMaxSize": 256000,
        "FullSyncReaderReadDocumentCount": 0,
        "FullSyncReaderWriteDocumentParallel": 8,
        "HTTPListenPort": 9100,
        "Id": "mongoshake",
        "IncrSyncAdaptiveBatchingMaxSize": 1024,
        "IncrSyncCollisionEnable": false,
        "IncrSyncConflictWriteTo": "none",
        "IncrSyncDBRef": false,
        "IncrSyncExecutor": 1,
        "IncrSyncExecutorDebug": false,
        "IncrSyncExecutorInsertOnDupUpdate": false,
        "IncrSyncExecutorMajorityEnable": false,
        "IncrSyncExecutorUpsert": false,
        "IncrSyncFetcherBufferCapacity": 256,
        "IncrSyncHTTPListenPort": 9100,
        "IncrSyncMongoFetchMethod": "change_stream",
        "IncrSyncOplogGIDS": [],
        "IncrSyncReaderBufferTime": 1,
        "IncrSyncReaderDebug": "discard",
        "IncrSyncShardKey": "collection",
        "IncrSyncTunnel": "",
        "IncrSyncTunnelAddress": [
            "mongodb://root:***@s-xxx-pub.mongodb.rds.aliyuncs.com:3717"
        ],
        "IncrSyncTunnelMessage": "json",
        "IncrSyncWorker": 8,
        "IncrSyncWorkerBatchQueueSize": 64,
        "IncrSyncWorkerOplogCompressor": "none",
        "LogDirectory": "",
        "LogFileName": "collector.log",
        "LogFlush": false,
        "LogLevel": "info",
        "MasterQuorum": false,
        "MongoConnectMode": "secondaryPreferred",
        "MongoCsUrl": "",
        "MongoSUrl": "",
        "MongoUrls": [
            "mongodb://xxx:31771,xxx:31772,xxx:31773"
        ],
        "SyncMode": "full",
        "SystemProfile": 9200,
        "SystemProfilePort": 9200,
        "TransformNamespace": [],
        "Tunnel": "direct",
        "TunnelAddress": [
            "mongodb://root:***@s-xxx-pub.mongodb.rds.aliyuncs.com:3717"
        ],
        "TunnelMessage": "json",
        "Version": "improve-2.4.1,6badf6dfa00ebc0fc1a34e4864814733c5849daf,release,go1.10.8,2020-04-03_16:15:00"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    1. 全量监控

    用户可以通过curl对应full_sync.http_port值来进行查看,目前提供了以下几个接口:

    1. conf。展示配置文件信息。
    2. progress。展示全量同步的进度。
    3. index。索引同步情况。(暂未开放)
    4. sentinel。控制全量运行,目前仅开放限速。

    1.1 progress同步进度展示。

    下面是一个同步进度的展示,具体说明请查看注释:

    vinllen@~/code/MongoShake$ curl -s  http://127.0.0.1:9101/progress | python -m json.tool
    {
        "progress": "23.40%", // 大概的进度,100%表示全量同步完成
        "total_collection_number": 47, // 一共有多少个表
        "finished_collection_number": 11, // 已经完成同步表的数目
        "processing_collection_number": 6, // 正在同步的表的数目
        "wait_collection_number": 30, // 等待同步的表的数目
        "collection_metric": { // 各个表同步的详细信息
            "a.b": "100.00% (4/4)", // db=a, collection=b, 同步完成100%,一共有4条数据,同步了4条数据
            "pock.hh": "9.20% (8064/87667)",  // db=pock, collection=hh, 同步完成9.20%,一共有87667条数据,同步了8064条数据
            "pock.hh2": "100.00% (28/28)",
            "test.mmm": "100.00% (1/1)",
            "test.test": "100.00% (7/7)",
            "ycsb.usertable2": "0.32% (3584/1113323)",
            "ycsb.usertable3": "0.26% (2176/822695)",
            "ycsb.usertable4": "0.51% (2176/428967)",
            "yy.x": "100.00% (4/4)",
            "zz-2018-12-11.cc1": "0.00% (0/289)",
            "zz-2018-12-11.cc2": "0.00% (0/308)",
            "zz-2018-12-11.cc3": "-", // -表示还未开始同步
            "zz-2018-12-12.cc1": "-",
            "zz.flush": "100.00% (1/1)",
            "zz.mmm": "100.00% (25/25)",
            "zz.x": "100.00% (42/42)",
            ... // 省略部分
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    有些情况collection同步的百分比可能会大于100%,例如,假设刚开始的时候源端文档有150条,后来在全量过程中,源端增加到了160条,但是同步的进度还是全量同步开始之前的按150条来算的(即使后来增加到了160条),所以对于这种情况显示的百分比就大于100%了,这个是正常现象。

    1.2 sentinel控制

    当前sentinel仅提供限速机制。需要注意的是,全量阶段的限速不是严格按照用户给定的速率进行限制,而是按照配置文件中full_sync.reader.document_batch_size的倍速限制。举个例子:

    • 配置100,意味着限速128
    • 配置128,意味着限速128
    • 配置129,意味着限速256
    • 配置1000,意味着限速1024
    查看sentinel

    用户可以先查看一下当前的sentinel配置

    vinllen@~/code/MongoShake$ curl -s 127.0.0.1:9101/sentinel | python -m json.tool
    {
        "TPS": 0 // 默认0表示不限速,非0表示启用限速
    }
    
    • 1
    • 2
    • 3
    • 4
    配置sentinel

    比如把限速0放开到1000:

    vinllen@~/code/MongoShake$ curl -X POST --data '{"TPS":1000}' 127.0.0.1:9101/sentinel/options
    {"sentinel":"success"}
    
    • 1
    • 2

    再次查看配置是否生效:

    vinllen@~/code/MongoShake$ curl -s 127.0.0.1:9101/sentinel | python -m json.tool
    {
        "TPS": 1000
    }
    
    • 1
    • 2
    • 3
    • 4

    具体当前的同步速率请查看日志层面提供的tps参数,例如下面这个tps是384:

    [17:57:02 CST 2020/04/07] [INFO] (mongoshake/common.(*ReplicationMetric).startup.func1:175) [name=zz-186-replica-3177x, stage=full, get=616833, tps=384]
    
    • 1

    注意:如果不需要限速请设置为0,不要设置一个过大的值,这将会消耗大量CPU资源。

    2. 增量监控

    用户可以通过curl对应incr_sync.http_port(v2.4.1开始)或者http_profile(v2.4.1之前)的值来进行查看,目前提供了以下几个接口,关于各个角色worker, executor, persister大家可能比较困惑,请参考内部架构介绍。

    1. conf。展示配置文件信息。
    2. repl。复制的整体信息,主要包括目前同步的checkpoint位点。
    3. queue。syncer内部的队列使用情况。
    4. worker。worker内部的基本情况。
    5. executor。写入端的统计情况。
    6. persist。内部角色persister的内部情况。
    7. sentinel。内部控制信息。
    8. sentinel/options。内部控制选项。

    2.1 repl

    复制的整体信息,主要包括目前同步的checkpoint位点。

    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/repl | python -m json.tool
    {
        "logs_get": 2, // 拉取的oplog的oplog总个数
        "logs_repl": 0,  // 尝试写入目的端的oplog总个数
        "logs_success": 0, // 成功写入的oplog个数
        "lsn": { // 已经拉取的checkpoint位点(不一定写入)
            "time": "1970-01-01 08:00:00", // 1970-01-01这个时间点是初始时间,表示还没有数据写入
            "ts": "0",
            "unix": 0
        },
        "lsn_ack": { // 已经成功写入目的端的checkpoint位点(已经成功写入,但是不一定持久化)
            "time": "1970-01-01 08:00:00",
            "ts": "0",
            "unix": 0
        },
        "lsn_ckpt": { // 已经成功持久化的checkpoint位点
            "time": "1970-01-01 08:00:00",
            "ts": "0",
            "unix": 0
        },
        "now": { // 当前的时间
            "time": "2020-04-03 18:32:28",
            "unix": 1585909948
        },
        "replset": "zz-186-replica-3177x", // 源端的名字
        "tag": "improve-2.4.1,6badf6dfa00ebc0fc1a34e4864814733c5849daf,release,go1.10.8,2020-04-03_18:19:37", // 当前MongoShake代码版本信息
        "tps": 0, // 同步的oplog速率qps
        "who": "mongoshake" // id
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    如果lsn_ckpt长期没有更新,跟now的时间越来越大,那么通常证明同步有异常了,要么是写流量过大导致差距变大,要么是同步中断了。对于3.4以后的版本,即使没有写入,也会定期产生noop oplog推动lsn_ckpt,但对于3.4以前,如果长期没写入,这个差距越来越大是正常现象。

    2.2 queue

    syncer内部的队列使用情况。

    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/queue | python -m json.tool
    {
        "logs_queue_size": 64, // logs_queue的总大小
        "pending_queue_size": 64, // pending_queue的总大小
        "persister_buffer_used": 0, // persister_buffer用了多少
        "syncer_inner_queue": [ // syncer内部queue的使用情况
            {
                "logs_queue_used": 0, // logs_queue用了多少,通常来说,如果塞满了=64,那么证明下游处理是瓶颈,为0通常是拉取是瓶颈,同理下面各个queue
                "pending_queue_used": 0, // pending_queue用了多少
                "queue_id": 0 // queue的id,对于副本集默认一共有4个,sharding的话一个shard对应一个
            },
            {
                "logs_queue_used": 0,
                "pending_queue_used": 0,
                "queue_id": 1
            },
            {
                "logs_queue_used": 0,
                "pending_queue_used": 0,
                "queue_id": 2
            },
            {
                "logs_queue_used": 0,
                "pending_queue_used": 0,
                "queue_id": 3
            }
        ],
        "syncer_replica_set_name": "zz-186-replica-3177x" // 源端mongo的名字
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2.3 worker

    worker内部的使用情况。

    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/worker | python -m json.tool
    [
        {
            "count": 0, // 当前worker已经同步了多少条数据
            "jobs_in_queue": 0, // 目前worker queue里面存在的个数
            "jobs_unack_buffer": 0, // 目前未ack的buffer的大小
            "last_ack": "0", // 已经ack的最后一条oplog的ts
            "last_unack": "0", // 上一个未ack的oplog的ts
            "worker_id": 0 // worker的id,用户可以在配置文件里面配置worker的个数
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 1
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 2
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 3
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 4
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 5
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 6
        },
        {
            "count": 0,
            "jobs_in_queue": 0,
            "jobs_unack_buffer": 0,
            "last_ack": "0",
            "last_unack": "0",
            "worker_id": 7
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    2.4 executor (2.4版本以后开放)

    写入到mongodb的统计,一个executor对应一个worker,默认情况下(incr_sync.shard_key = collection),一个表的同步只会写到一个executor,但是一个executor可能对应多个表。

    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/executor | python -m json.tool
    [
        {
            "ddl": 0, // 多少条ddl数据写入目的MongoDB
            "delete": 0, // 所少条删除数据写入目的MongoDB
            "error": 0, // 写入出错次数有多少
            "id": 0, // 当前executor的id
            "insert": 0, // 多少条insert语句写入目的MongoDB
            "unknown": 0, // 数据类型为止
            "update": 0 // 多少条update语句写入目的MongoDB
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 1,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 2,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 3,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 4,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 5,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 6,
            "insert": 0,
            "unknown": 0,
            "update": 0
        },
        {
            "ddl": 0,
            "delete": 0,
            "error": 0,
            "id": 7,
            "insert": 0,
            "unknown": 0,
            "update": 0
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    2.5 sentinel和sentinel/options

    sentinel/options可以控制内部的一些信息,比如临时暂停链路(后续可以恢复),限制同步的速率TPS等。sentinel展示当前的配置结果。

    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/sentinel | python -m json.tool
    {
        "DuplicatedDump": false, // 如果插入目的端发现重复,是否把这个冲突数据给dump下来,dump的位置参考incr_sync.conflict_write_to参数
        "OplogDump": 0, // 是否打印每一条oplog,0表示不打印,1表示采样打印,2表示全部打印
        "Pause": false, // 是否停止当前链路
        "TPS": 0 // 当前同步的tps/qps多少
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    v2.4.6版本新增TargetDelay用于延迟同步,接口请参考:v2.4.6版本增加延迟同步功能 sentinel/options用于设置上面参数,直接curl post就行,例如,暂停链路:

    vinllen@~/code/MongoShake$ curl -X POST --data '{"Pause": true}' http://127.0.0.1:9100/sentinel/options
    {"sentinel":"success"}
    vinllen@~/code/MongoShake$ curl -s http://127.0.0.1:9100/sentinel | python -m json.tool
    {
        "DuplicatedDump": false,
        "OplogDump": 0,
        "Pause": true, // 可以看到这里已经是true了
        "TPS": 0 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    对 JavaBean 的特点写法与实战心得详解
    2023年数维杯国际赛B题赛题解题思路+部分代码
    超详细的VsCode创建SpringBoot项目(图文并茂)
    实验六 TCP及应用分析
    混合策略改进的蝴蝶优化算法-附代码
    调用华为API实现身份证识别
    ChromeOptions 设置WebDriver/ChromeDriver的请求头参数
    基于PHP的高效协同办公管理系统
    Shell脚本相互调用并指定返回值
    Vue学习:webpack-dev-server和nginx问答
  • 原文地址:https://blog.csdn.net/u014650965/article/details/128069447