这是《MongoDB 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Chunk 迁移由 Balancer 触发,用于把数据块从负载或数据量较高的 shard 移到较低 shard。迁移影响磁盘 IO、网络、oplog、缓存和查询延迟,必须通过窗口控制和监控治理。
17.1 为什么迁移
触发原因:
- shard 之间 chunk 数不均衡;
- 数据量差异超过阈值;
- 新增 shard;
- 分片键热点变化;
- 手动移动 chunk;
- zone 策略调整。
目标:
shard 1 100 chunks
shard 2 100 chunks
shard 3 100 chunks
17.2 Balancer
查看:
sh.status()
sh.isBalancerRunning()
停止:
sh.stopBalancer()
启动:
sh.startBalancer()
设置均衡窗口:
db.settings.updateOne(
{ _id: "balancer" },
{ $set: { activeWindow: { start: "02:00", stop: "06:00" } } },
{ upsert: true }
)
17.3 迁移流程
balancer selects chunk
-> source opens migration
-> target clones chunk data
-> target catches up changes
-> config metadata commit
-> source deletes data
阶段:
| 阶段 | 影响 |
|---|---|
| clone | 源和目标磁盘、网络 |
| catch up | 复制增量修改 |
| commit | config 元数据变更 |
| delete | 源 shard 删除旧数据 |
删除阶段可能带来明显 IO 压力。
17.4 迁移控制
常用做法:
- 设置低峰窗口;
- 限制并发迁移;
- 新 shard 灰度加入;
- 控制大批量导入节奏;
- 迁移期间避免重建索引;
- 观察复制延迟;
- 磁盘预留空间。
新增 shard 后Balancer 会逐步迁移数据,不要期望瞬间完成。
17.5 手动迁移
查看 chunk:
use config
db.chunks.find({ ns: "shop.orders" }).sort({ min: 1 }).limit(5)
移动示例命令名称和参数随版本变化,应使用当前版本文档确认。生产手工移动前必须:
- 记录 chunk 范围;
- 确认目标 shard 空间;
- 停止业务大批量操作;
- 预估迁移时间;
- 保留回滚方案。
17.6 Zone 与数据局部性
创建 zone:
sh.addShardTag("shard-us", "us")
关联范围:
sh.addTagRange(
"shop.orders",
{ region: "us", user_id: MinKey },
{ region: "us", user_id: MaxKey },
"us"
)
适用:
- 数据合规驻留;
- 就近访问;
- 冷热 shard 隔离;
- 业务域隔离。
Zone 设计错误可能导致数据无法迁移或分布异常。
17.7 迁移与备份
迁移会带来挑战:
- 快照时可能存在进行中的迁移;
- Config 元数据必须与 shard 数据对应;
- 恢复演练要验证路由;
- 混合备份需要时间点一致性;
- 恢复后观察 chunk 分布。
建议:
- 备份窗口避开均衡窗口;
- 备份 Config Server;
- 使用官方备份机制或经过验证的快照流程;
- 保留集群拓扑版本。
17.8 常见问题
| 问题 | 排查 |
|---|---|
| 迁移一直进行 | 数据倾斜、chunk 太大、写入持续 |
| 查询延迟升高 | 迁移 IO、缓存污染 |
| 复制延迟升高 | Secondary 追加变更 |
| 新 shard 没数据 | Balancer 停止或窗口未到 |
| 删除阶段磁盘高 | 源 shard 清理 |
| 元数据不一致 | config 状态、迁移失败 |
17.9 监控指标
balancer_running
chunks_total
chunks_per_shard
data_size_per_shard
migrations_in_progress
migration_duration_ms
migration_failure_total
shard_disk_usage
shard_cache_pressure
告警:
- 迁移长期卡住;
- shard 数据持续倾斜;
- 迁移失败率高;
- 迁移期间复制延迟超过阈值;
- 某个 shard 磁盘水位过高。
本章小结
Chunk 迁移让分片集群保持数据均衡,但迁移本身是有成本的在线操作。生产上必须配置均衡窗口,监控迁移状态、磁盘、网络和复制延迟,并在新增节点或大批量写入时控制节奏。
思考题
- Balancer 的目标是什么?
- 迁移的删除阶段为什么可能带来压力?
- 为什么迁移窗口要避开备份和高峰?
- Zone 适合解决什么问题?
- shard 数据倾斜通常由什么造成?