後台任務(繼承 BackgroundJob),周期性檢查 Chunk 分佈,將過載 Shard 的 Chunk 遷移至閒置 Shard,實現數據均衡。

BalancerPolicy:策略介面,決定哪些 Chunk 需遷移。CandidateChunk:待遷移 Chunk 信息。Balancer::run()void Balancer::run() {
while (!inShutdown()) {
if (!_init()) { sleep(60); continue; } // 連接配置服務器
break;
}
ConnectionString config = configServer.getConnectionString();
DistributedLock balanceLock(config, "balancer"); // 分布式鎖,防多 Mongos 衝突
while (!inShutdown()) {
if (!grid.shouldBalance()) { sleep(30); continue; } // 均衡功能關閉
// 1. 獲取分布式鎖
if (!balanceLock.try_lock()) { sleep(10); continue; }
// 2. 收集候選 Chunk
vector<CandidateChunkPtr> candidates;
ScopedDbConnection conn(config);
_doBalanceRound(conn, &candidates);
// 3. 執行遷移
int moved = _moveChunks(&candidates);
_balancedLastTime = moved;
balanceLock.unlock();
sleep(moved ? 5 : 10); // 有遷移則 5s 後繼續,否則 10s
}
}
BalancerPolicy::getCandidateChunks() 找出「最重 Shard → 最輕 Shard」的遷移對。CandidateChunk,調用 moveChunk()(發送 moveChunk 命令給源 Shard)。migrating,讀寫請求由 Mongos 路由到正確位置。DistributedLockconfig.locks 集合實現。_id, state, who, ts。try_lock() 用 findAndModify 原子搶佔;unlock() 釋放。chunkSize:Chunk 最大體積,影響分裂與遷移粒度。balancerWindow:允許均衡的時間窗口。_balancedLastTime:上輪遷移數,動態調整睡眠間隔。Balancer 以後台線程 + 分布式鎖 + 策略模式實現自動化數據均衡。核心難點在於元數據一致性(Config Server 鎖)、遷移過程的原子性(兩階段提交)、策略的可擴展性(Policy 接口)。