本文档为指导您在执行删减分片操作时,如何排查任务阻塞的原因以及解决方法。
步骤一:确认均衡器(Balancer)状态
数据迁移完全依赖均衡器(Balancer)完成。如果 Balancer 未开启,待删除分片上的数据将无法迁出,导致删除任务被阻塞。
检查方法
方法1:在 控制台 的参数配置页面,查看 openBalance.window 参数的当前运行值。若为 false,则表示 Balancer 未开启;若为 true,则表示已开启 Balancer。
方法2:执行
sh.getBalancerState(),若返回 false,则表示 Balancer 未开启;若返回 true,则表示已开启 Balancer。解决方法
步骤二:检查均衡器活动窗口
Balancer 仅在设定的“活动窗口期”内进行数据迁移。如果窗口期过小,会极大拖慢迁移进度。
检查方法
方法1:在 控制台 的参数配置页面,查看 balance.window 参数的当前运行值,获取当前的均衡器时间窗。
方法2:执行
sh.getBalancerWindow(),返回窗口期的起止时间{ "start" : "00:30", "stop" : "02:30" }。解决方法
步骤三:获取任务进度信息
查看待删除分片上还有多少数据(Chunk)需要迁移。
1. 查看删减分片上需要迁移的 Chunks 数量。
说明:
分片名称格式:cmgo-xxxxxxxx_n,其中,xxxxxxxx 为实例唯一标识(8位字符);n 为分片序号,从0开始编号。例如,一个5分片实例,分片名为 cmgo-xxxxxxxx_0 到 cmgo-xxxxxxxx_4,如果客户要删减最后一个分片,就应该指定 cmgo-xxxxxxxx_4。
建议在从节点上执行查询操作,避免对主节点造成性能影响。
mongos> db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "cmgo-xxxxxxxx_3"}},{$group: {_id: "$ns", count: {$sum: 1}}}]){ "_id" : "config.system.sessions", "count" : 1960 }
如果 Chunk 数较大,建议按集合分别查询。
db.getSiblingDB("config").chunks.aggregate([{ $match: {shard: "cmgo-xxxxxxxx_2",ns: { $in: [ "config.system.sessions" ] }}},{ $group: {_id: "$ns",count: { $sum: 1 }}}])
2. 查看迁移速率,查询过去24小时的迁移的 Chunk 数量。
// details.from指定chunk迁移的目标shard// time字段用ISODate指定时间范围mongos> db.getSiblingDB("config").changelog.find({"what": "moveChunk.commit","details.from": "cmgo-xxxxxxxx_3","time": {$gte: ISODate("2025-11-14T00:00:00Z"),$lt: ISODate("2025-11-15T00:00:00Z")}}).count()256
步骤四:预估任务完成时间
在理想情况下(业务负载稳定,Chunk 总数不变),您可以根据上述信息进行估算:
预计完成时间 ≈ 需迁移 Chunk 数 / 过去24小时迁移的 Chunk 数
例如:需迁移 Chunk 数 = 1960,过去24小时迁移的 Chunk 数 = 256,则预计完成时间为:1960 / 256 ≈ 8 (天)。
步骤五:诊断任务阻塞
如果发现长时间没有 Chunk 迁移成功,且待删除分片上始终残留部分 Chunk,则任务很可能已被阻塞。
最常见的原因:Jumbo Chunk(超大块)
因分片键设计不合理(如存在热点Key)可能导致某些 Chunk 超出最大尺寸限制,无法被迁移,从而阻塞整个删除任务。
检查命令:查询待删除分片上的 Jumbo Chunk。
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "cmgo-xxxxxxxx_n", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])
解决方法
1. 优化分片键:
MongoDB 4.4:使用 refineCollectionShardKey 命令为原分片键添加后缀,增大其基数。
MongoDB 5.0+:使用 reshardCollection 命令为集合设置新的分片键。
2. 删除数据:如果业务允许,可以自行删除 Jumbo Chunk 内的部分数据,使其尺寸变小。
3. 调整参数:调大 chunkSize 参数,改变 Jumbo Chunk 的判定标准。