将集合重新分片为相同的分片键
关于此任务
通过重新分片到相同的分片键,您可以将重新分片用作数据移动机制。这使您能够:
使用 Reshard to Shard 技术对集合分片,并将其数据分布到所有相关分片
更快地添加新分片
更快地删除分片
重写集合以回收磁盘空间
重新分片操作按顺序执行以下阶段:
克隆阶段复制当前的集合数据。
构建索引阶段在重新分片的集合上构建索引。
追赶阶段将所有待处理的写入操作应用于重新分片的集合。
提交阶段会重命名临时集合并删除旧集合以执行切换。
开始之前
在重新分片之前,您必须计算集群的 存储要求、延迟要求和任何其他资源要求。
存储要求
假设最小oplog window为 24 小时,通过将集合大小和索引大小相加,使用以下公式计算重新分片操作所需的存储空间:
Available storage required on each shard = [(collection size + index size) *2 ] / number of shards the collection will be distributed across.
示例,一个 2TB 的集合和分布式在 4 个分片上的 400 GB的索引,每个分片至少需要 1.2TB 的可用存储:
[ (2 TB + 400GB) * 2 ] / 4 shards = 1.2 TB / shard
您必须确认集群中有可用的存储空间。
如果可用空间或 I/O 空间不足,则必须增加存储大小。如果 CPU 空间不足,则必须选择更大的实例大小来扩展集群。
提示
如果您的MongoDB 集群托管在Atlas上,则可以使用Atlas用户界面查看存储、CPU 和 I/O 空间指标。
延迟要求
您必须确保应用程序可以容忍正在重新分片的集合阻塞写入的两秒钟时间。当写入受阻时,应用程序的延迟会增加。如果您的工作负载无法容忍此要求,请使用数据块迁移来平衡集群。
其他资源要求
您的集群必须满足这些额外要求:
最小oplog window为 24 小时。
I/O容量低于 50%。
CPU 负载低于 80%。
步骤
对集合重新分片。
使用 reshardCollection
命令,并将 forceRedistribution
选项设立为 true
,对集合进行重新分片。 reshardCollection
命令采用以下语法:
db.adminCommand( { reshardCollection: "<database>.<collection>", key: { "<shardkey>" }, unique: <boolean>, numInitialChunks: <integer>, collation: { locale: "simple" }, zones: [ { min: { "<document with same shape as shardkey>" }, max: { "<document with same shape as shardkey>" }, zone: <string> | null }, ], forceRedistribution: <bool> } )
示例,此命令将在其当前分片键{ product_SKU : 1 }
上对 info.productsInformation
集合重新分片:
db.adminCommand( { reshardCollection: "info.productsInformation", key: { product_SKU : 1 }, forceRedistribution: true } )
监控重新分片操作。
要监控重分片操作,可以使用 $currentOp
管道阶段:
db.getSiblingDB("admin").aggregate( [ { $currentOp: { allUsers: true, localOps: false } }, { $match: { type: "op", "originatingCommand.reshardCollection": "<database>.<collection>" } } ] )
注意
要查看更新后的值,您需要持续运行管道。
$currentOp
管道输出:
totalOperationTimeElapsedSecs
:经过的操作时间(以秒为单位)remainingOperationTimeEstimatedSecs
:当前重新分片操作的预计剩余时间(以秒为单位)。当新的重新分片操作开始时,将返回-1
。从MongoDB 7.0 开始,在重新分片操作期间,
remainingOperationTimeEstimatedSecs
在协调器上也可用。remainingOperationTimeEstimatedSecs
设置为悲观的时间估计值:将追赶阶段时间估计值设置为克隆阶段时间,这是一个相对较长的时间。
实际上,如果只有几个待处理的写入操作,则实际的追赶阶段时间相对较短。
[ { shard: '<shard>', type: 'op', desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>', op: 'command', ns: '<database>.<collection>', originatingCommand: { reshardCollection: '<database>.<collection>', key: <shardkey>, unique: <boolean>, collation: { locale: 'simple' } }, totalOperationTimeElapsedSecs: <number>, remainingOperationTimeEstimatedSecs: <number>, ... }, ... ]