首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

MongoDB 源碼分析:Mongos Balancer 均衡器實現

     編輯:關於C語言

Balancer 角色

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

類結構

Balancer Class Diagram

  • 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
    }
}

關鍵步驟詳解

_doBalanceRound():收集遷移候選

  • 遍歷所有集合的 Chunk 分佈。
  • 計算每個 Shard 的 Chunk 數、數據量。
  • 調用 BalancerPolicy::getCandidateChunks() 找出「最重 Shard → 最輕 Shard」的遷移對。

_moveChunks():逐個遷移

  1. 對每個 CandidateChunk,調用 moveChunk()(發送 moveChunk 命令給源 Shard)。
  2. 源 Shard 讀取 Chunk 數據 → 發送給目標 Shard → 目標確認 → 更新 Config Server 元數據。
  3. 遷移期間 Chunk 標記為 migrating,讀寫請求由 Mongos 路由到正確位置。

分布式鎖 DistributedLock

  • 基於 Config Server 的 config.locks 集合實現。
  • 鎖文檔含 _id, state, who, ts。
  • try_lock() 用 findAndModify 原子搶佔;unlock() 釋放。
  • 防止多 Mongos 同時均衡導致元數據衝突。

配置參數影響

  • chunkSize:Chunk 最大體積,影響分裂與遷移粒度。
  • balancerWindow:允許均衡的時間窗口。
  • _balancedLastTime:上輪遷移數,動態調整睡眠間隔。

總結

Balancer 以後台線程 + 分布式鎖 + 策略模式實現自動化數據均衡。核心難點在於元數據一致性(Config Server 鎖)、遷移過程的原子性(兩階段提交)、策略的可擴展性(Policy 接口)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved