利用MongoDB的SplitVector命令实现并发数据迁移

摘要:背景 数据迁移是数据库运维中一个很常见的场景。数据迁移分为全量和增量。为了追求速度,通常我们会采用并发的方式对数据进行全量迁移。在全量导出数据时,通常都会选择做到记录级的并发,因此通常会涉及到对需要导出的某个表(集合)按照并发度进行切分(分区)的过程。

背景
数据迁移是数据库运维中一个很常见的场景。数据迁移分为全量和增量。为了追求速度,通常我们会采用并发的方式对数据进行全量迁移。在全量导出数据时,通常都会选择做到记录级的并发,因此通常会涉及到对需要导出的某个表(集合)按照并发度进行切分(分区)的过程。现有常用做法是通过若干个skip加limit来找到一些分区点,然后就可以并发同时导出多个分区。事实上MongoDB还有一个SplitVector命令特别适合用来做集合的分区。本文将介绍一下如何利用这个命令来对集合做分区,实现并发数据迁移。
命令简介
SplitVector命令原是在sharding中chunk分裂时需要用的一个内部命令,是mongos在准备分裂某个chunk前发给这个chunk所在shard以计算分裂点(SplitPoint)时使用的。但是这个命令也可以用于普通的副本集,我们可以把副本集中的集合看作一个唯一的chunk,利用这个命令来为这个chunk计算分裂点,从而达到为某个集合进行分区的目的。
SplitVector命令的使用在官方文档中没有介绍,只说明了其实一个内部命令,但是使用命令的Help却可以看到:
db.runCommand({splitVector:"test.test", help:1})
{
"help" : "help for: splitVector Internal command.\nexamples:\n{ splitVector : \"blog.post\" , keyPattern:{x:1} , min:{x:10} , max:{x:20}, maxChunkSize:200 }\nmaxChunkSize unit in MBs\nMay optionally specify 'maxSplitPoints' and 'maxChunkObjects' to avoid traversing the whole chunk\n\n{ splitVector : \"blog.post\" , keyPattern:{x:1} , min:{x:10} , max:{x:20}, force: true }\n'force' will produce one split point even if data is small; defaults to false\nNOTE: This command may take a while to run",
"lockType" : 0,
"ok" : 1
}
从帮助文档中可以大致看到,这个命令大致是这么使用的:
db.runCommand({splitVector:"blog.post", keyPattern:{x:1}, min{x:10}, max:{x:20}, maxChunkSize:200})
接下来介绍一下各个参数及其含义。
字段类型描述splitVectorstringsplitVector的操作对象集合名keyPatterndocumentchunk分裂使用的分区键,必须拥有索引,在sharding中就是shard key,在副本集中通常就指定成主键_id索引mindocument可选参数,分区数据集的最小值,如果没有指定,那么使用MinKeymaxdocument可选参数,分区数据集的最大值,如果没有指定,那么使用MaxKeymaxChunkSizeinteger可选参数,和『force』参数二者必须指定一个。分区后每个chunk的最大大小maxSplitPointsinteger可选参数,分裂点个数上限maxChunkObjectsinteger可选参数,分区后每个chunk最大包含的记录数,默认为250000forceboolean可选参数,和『maxChunkSize』参数二者必须指定一个。默认情况下如果当前chunk的数据大小小于maxChunkSize则不会进行分裂。如果指定了『force』为true,那么会强制在当前chunk的中位点进行分裂,返回一个分裂点。默认为false。
这么多参数到底怎么用呢?我怎么知道出来的结果是怎样的?没有更详细的文档,只有啃源码了。?



利用MongoDB的SplitVector命令实现并发数据迁移
文章图片
【利用MongoDB的SplitVector命令实现并发数据迁移】原文链接

    推荐阅读