在ApsaraDB for MongoDB分區叢集執行個體增刪Shard節點、資料移轉等情境下,您可能需要修改均衡器Balancer的使用中視窗期或開啟關閉均衡器Balancer。本文介紹如何管理均衡器Balancer。
功能簡介
均衡器Balancer用於均衡分區叢集執行個體中各Shard節點中的資料,不同版本的MongoDB執行個體工作原理存在區別:
-
MongoDB 5.0及以前版本:
Balancer會監控分區叢集執行個體中各個Shard節點上的Chunk(塊)數量,當某個Shard節點上的Chunk數量達到遷移閾值時,Balancer會對Shard節點上的Chunk進行遷移(moveChunk),盡量保證每個Shard節點上的Chunk數量相同。不同版本的遷移閾值存在差異,具體資訊如下。
資料庫版本
遷移閾值
MongoDB 3.2(已停售)
-
Chunk總數<20,遷移閾值為2。
-
20≤Chunk總數≤80,遷移閾值為4。
-
80≤Chunk總數,遷移閾值為8。
MongoDB 3.4(已停售)
MongoDB 4.0
-
預設遷移閾值為2。
-
如果Chunk總數小於20個,或者上次遷移的Chunk數量小於20個,遷移閾值為1。
MongoDB 4.2
MongoDB 4.4
MongoDB 5.0
遷移閾值為1。
-
-
MongoDB 6.0 及以後版本:
由於Jumbo Chunk的存在,根據Chunk數量均衡資料可能會出現各Shard節點上Chunk數量相同,但是磁碟空間使用大小卻不同的情況。為解決上述問題,自ApsaraDB for MongoDB6.0版本起,Balancer變為監控分區叢集執行個體中各個Shard節點上同一集合的資料大小情況,當集合在各Shard節點上的資料大小差異超過384 MB時(三倍的Chunk Size),Balancer會根據Shard Tag分割資料再遷移(moveRange)至其他Shard節點。
如果您需要判斷資料是否均衡,可以通過
getShardDistribution()命令查看集合的資料分布情況,無需再關注Chunk這個邏輯概念,只需專註於集合資料大小即可。說明升級到6.0版本(小版本7.0.1及以上)或更高版本後,您可能會發現通過
sh.status()查看到各Shard上的Chunk數量不再均衡,甚至合并為1個,這是新版本Balancer的正常行為。詳情請參見升級MongoDB執行個體後,各分區Chunks數量不均衡。
注意事項
-
僅分區叢集執行個體支援Balancer功能。
-
Balancer預設處於開啟狀態。如未開啟,請參見開啟Balancer功能。
-
Balancer的使用中視窗期預設為全天,當Balancer執行塊遷移時,可能會影響資料庫效能。為避免塊遷移給您的業務帶來影響,建議您將Balancer的使用中視窗期修改為業務低峰期。設定使用中視窗期的方法,請參見設定Balancer的使用中視窗。
-
本文的樣本均通過Mongo Shell進行操作,其他用戶端工具管理Balancer的方法以及返回資訊可能與本文樣本存在差異。
設定Balancer的使用中視窗
-
在mongos節點命令視窗中,切換至config資料庫。
use config -
執行如下命令設定Balancer的使用中視窗。
db.settings.update( { _id: "balancer" }, { $set: { activeWindow : { start : "<start-time>", stop : "<stop-time>" } } }, { upsert: true } )說明-
<start-time>:開始時間,時間格式為HH:MM(執行個體所在地區的當地時間),HH取值範圍為00~23,MM取值範圍為00~59。 -
<stop-time>:結束時間,時間格式為HH:MM(執行個體所在地區的當地時間),HH取值範圍為00~23,MM取值範圍為00~59。
例如,您需要將Balancer活躍視窗期修改為每天淩晨的1點到3點,樣本如下:
db.settings.update( { _id: "balancer" }, { $set: { activeWindow : { start : "01:00", stop : "03:00" } } }, { upsert: true } )設定成功後,您可以執行
sh.status()命令查看Balancer的使用中視窗。返回樣本如下。
-
相關操作:如您需要Balancer始終處於運行狀態,您可以執行如下命令去除使用中視窗的設定。
db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })
開啟Balancer功能
如果您設定了資料分區,開啟Balancer功能後可能會立即觸發均衡任務。這將佔用執行個體的資源,請在業務低峰期執行該操作。
-
在mongos節點命令視窗中,切換至config資料庫。
use config -
執行如下命令開啟Balancer功能。
sh.setBalancerState(true)
關閉Balancer功能
均衡器Balancer預設處於開啟狀態。如果需臨時關閉,請參見以下步驟進行操作。
關閉Balancer功能後,Balancer將不會再均衡各Shard節點中的資料,可能會導致資料扭曲。
-
在mongos節點命令視窗中,切換至config資料庫。
use config -
執行
sh.isBalancerRunning()命令查看Balancer運行狀態。sh.isBalancerRunning()命令會依據Mongo Shell用戶端的版本返回不同的結果,返回結果目前有布爾值和Map兩種:-
布爾值
-
傳回值為false,表示Balancer沒有處於執行任務的狀態,此時可執行關閉Balancer操作。
-
傳回值為true,表示Balancer正在執行塊遷移,此時不能執行關閉Balancer的命令,否則可能引起資料不一致。
-
-
Map
{ mode: 'full', inBalancerRound: false, numBalancerRounds: Long("1143"), ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1639753724, i: 3 }), signature: { hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0), keyId: Long("0") } }, operationTime: Timestamp({ t: 1639753724, i: 3 }) }-
如果inBalancerRound為false,表示Balancer沒有處於執行任務的狀態,此時可執行關閉Balancer操作。
-
如果inBalancerRound為true,表示Balancer正在執行塊遷移,此時不能執行關閉Balancer的命令,否則可能引起資料不一致。
-
更多關於
sh.isBalancerRunning()的介紹,請參見sh.isBalancerRunning()。 -
-
確認執行第3步的命令後返回的值為空白,可執行關閉Balancer命令。
sh.stopBalancer()
常見問題
開啟均衡器 Balancer 後產生孤兒文檔是否正常及如何處理
開啟均衡器 Balancer 後出現孤兒文檔,通常是因為 Chunk 遷移中斷、復原,或者分區鍵分布異常,導致 moveChunk 操作殘留資料。
Balancer 頻繁遷移 Chunk 期間,孤兒文檔數量短暫波動屬於正常現象。只要 Chunk 遷移結束後孤兒文檔數量最終降為 0,且孤兒文檔並非長期持續存在,通常無需擔心。
當集合間的資料量差異超過預設閾值(例如 200 多 MB)時,會自動觸發均衡。該均衡過程中可能短暫產生孤兒文檔。
如果孤兒文檔長期存在,請按以下順序排查和處理:
-
檢查 Balancer 日誌,確認是否存在 Chunk 遷移異常。
-
檢查分區鍵是否合理,確保資料分布均勻。
-
確認 Chunk 遷移完成後,執行
cleanupOrphaned命令清理孤兒文檔。