![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yZulGdhJ3Zp1WLn5WakJXYoN3LcNXZnFWbp91LcJjLzY3Lc12bj5iYk92Zu9WbuM3YvR2Lc9CX6MHc0RHaiojIsJye.png)
如果不了解 mongodb sharded cluster 原理,請先閱讀
<a href="https://yq.aliyun.com/articles/32434?spm=5176.8091938.0.0.5cqblw">mongodb sharded cluster架構原理</a>
<a href="https://yq.aliyun.com/articles/60096?spm=5176.8091938.0.0.ia5ha5">關于mongodb sharding,你應該知道的</a>
關于 sharding 遷移,會分3個部分來介紹,本文為第二部分
<a href="https://yq.aliyun.com/articles/60881?spm=5176.8091938.0.0.1448o4">負載均衡及遷移政策</a>
chunk 遷移流程
balancer 運維管理
movechunk的主要參數清單如下
參數
含義
movechunk
指定namespace(集合名)
find
通過查詢條件來指定要遷移的 chunk
bound
通過上下限來指定要遷移的 chunk,上下限必須要跟 chunk 的範圍完全比對
to
遷移目标 shard 名
歸根結底就是要指定『遷移哪個集合的哪個 chunk』,『把這個 chunk 遷移到哪個 shard』,選擇 chunk 時,可以通過 find 或 bound 2種方式來指定(兩者隻能選擇一個),mongos 就能計算出要遷移哪個 chunk,并知道 chunk 所在的源 shard。
mongos 接下來會構造根據上述參數,向源 shard 發送一個 movechunk 指令(mongos 和 shard 都支援 <code>movechunk</code> 這個指令,但内部的實作邏輯不同),接下來所有的遷移工作就由源 shard 接受了,等遷移完全結束,向 mongos 回報執行結果。
mongos 接受到使用者發送的遷移 chunk 指令,或者因負載均衡政策需要遷移 chunk,會建構一個 <code>movechunk</code> 的指令,并發送給源 shard。
源 shard 收到 mongos 發送的 movechunk 指令後,會向目标 shard 發送 <code>_recvchunkstart</code> 的指令,通知目标 shard 開始遷移資料(真正的資料遷移由目标shard 主動發起)。接下來,源 shard 會記錄該 chunk 在遷移過程中的所有增量修改操作。
目标 shard 接受到 <code>_recvchunkstart</code> 指令後,就會啟動單獨的線程來讀取 chunk 資料并寫到本地,主要步驟包括:
目标 shard 建立集合及索引(如果有必要)
如果遷移的集合在目标 shard 上沒有任何 chunk,則需要先在目标 shard 上建立集
合,并建立跟源 shard 上集合相同的索引
目标 shard 清理髒資料 (如果有必要)
如果目标 shard 上已經存在該 chunk 範圍内的資料,則肯定為某次遷移失敗導緻的髒資料,先将這些資料清理掉。
目标 shard 向源 shard 發送 <code>_migrateclone</code> 指令讀取 chunk 範圍内的所有文檔并寫入到本地,即遷移 chunk 全量資料,遷移完後更新狀态為 steady(可以了解為全量遷移完成的狀态)。
源 shard 會不斷調用查詢目标 shard 上的遷移狀态,看是否為 steady 狀态,如果已經是 steady 狀态,就會停止源 shard 上的寫操作(通過對集合加互斥寫鎖實作)。接下來發送 <code>_recvchunkcommit</code> 告訴目标 shard 不會再有新的寫入了。
目标 shard 的遷移線程不斷向源 shard 發送 <code>_transfermods</code> 指令,讀取遷移過程中的增量修改,并應用到本地,增量遷移完成後,向源确認 <code>_recvchunkcommit</code> 的結果。
源 shard 收到 <code>_recvchunkcommit</code> 的結果,整個資料遷移的步驟完成。
chunk 遷移到目标 shard 後,源上的 chunk 就沒有必要再儲存了,源 shard 會将 chunk 資料删除,預設情況下源 shard 會将删除操作加入到隊列,異步删除,如果 movechunk 時,指定了 _waitfordelete 參數為 true,則同步删除完再傳回。
--
2016-09-28 11:35:47 update
一旦源shard 查詢到目标 shard 進入到 steady 狀态了,源 shard 就會進入臨界區,測試源上的寫就會排隊等待。等整個遷移完了,這些等待的寫操作就會繼續執行,但此時 chunk 的版本号已經更新了,會告訴用戶端版本過低,用戶端重新從 config server 讀取配置,此時拿到的路由資訊裡 chunk 已經在目标 shard 了,然後寫會發往目标 shard 。
本文粗略的介紹了 chunk 遷移的主要流程,chunk 的遷移會受 balancer 政策、chunksize等很多因素影響,第三部分将會介紹遷移相關的運維管理,以便大家更好的管理 mongodb sharded cluster。
<a href="https://docs.mongodb.com/manual/reference/command/movechunk/">movechunk command</a>
<a href="https://www.aliyun.com/product/mongodb">mongodb雲資料庫</a>