这篇档为指导你在执行删减分片操作时,如何排查任务阻塞的原因以及解决方法。
一、步骤一:确认均衡器(Balancer)状态
数据迁移完全依赖均衡器(Balancer)完成。如果 Balancer 未开启,待删除分片上的数据将无法迁出,导致删除任务被阻塞。
二、检查方法
·方法1:在 控制台 的参数配置页面,查看 openBalance.window 参数的当前运行值。若为 false,则表示 Balancer 未开启;若为 true,则表示已开启 Balancer。
·方法2:执行 sh.getBalancerState(),若返回 false,则表示 Balancer 未开启;若返回 true,则表示已开启 Balancer。
三、解决方法
在 控制台 的参数配置页面,单击修改运行值,将 openBalance.window 参数设置为 true 开启均衡器。具体开启操作,请参见 调整数据库参数。
四、步骤二:检查均衡器活动窗口
Balancer 仅在设定的“活动窗口期”内进行数据迁移。如果窗口期过小,会极大拖慢迁移进度。
五、检查方法
·方法1:在 控制台 的参数配置页面,查看 balance.window 参数的当前运行值,获取当前的均衡器时间窗。
·方法2:执行 sh.getBalancerWindow(),返回窗口期的起止时间{ "start" : "00:30", "stop" : "02:30" }。
六、解决方法
在 控制台 的参数配置页面,单击修改运行值,可适当调大 balance.window 参数的时间窗。具体操作,请参见 调整数据库参数。
七、步骤三:获取任务进度信息
查看待删除分片上还有多少数据(Chunk)需要迁移。
1. 查看删减分片上需要迁移的 Chunks 数量。
注意:说明:
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 的判定标准。
删减分片会触发数据迁移,可能对实例负载带来长时间影响。建议你优先评估直接降低 Mongod 节点规格来达到降低成本的目的。具体操作,请参见 变更 Mongod 节点配置规格。