您好,登錄后才能下訂單哦!
本篇文章為大家展示了MongoDB中怎么實現分片管理,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
塊也叫區間,可能存在一分片一區間和一分片多區間兩種情況。
一分片一區間:數據不會在片之間自動移動來保持分片的數據的均勻性,需要手動拆分分片來移動數據。
而一分片多區間情況:一個數據塊默認64MB,當數據塊達到64MB時就會創建新的塊,當然前提是當前的粒度還允許再拆分,平衡器會保證每個分片數據塊的均勻。但是移動塊也遵循分片的原則,塊之間的數據集不能有交集。
比如一個塊[50-100)現在拆分成兩個塊,那么默認會拆分成[50-75)[75-100)兩個塊,如果當前分片塊比其它分片的塊大于9那么可能[75-100)改塊會被移動到新的分片當中。
平衡器(balancer)負責數據的遷移。它會周期性地檢查分片間是否存在不平衡,如果存在,則會開啟塊的遷移。不平衡的表現指,一個分片明顯比其他分片擁有更多的塊。假如有一些集合達到了閾值,平衡器則會開始做塊遷移。它會從負載比較比較大的分片中選擇一個塊,并詢問該分片是否需要在遷移之前對塊進行拆分。完成必要的拆分后,就會將塊遷移至數量比較少的機器上。
需要顯示隱藏的分片信息執行
所有的配置信息都保存在配置服務器的config數據庫中。
actionlog
記錄平衡器的相關操作日志。
changelog
跟蹤記錄集群的操作,包括集合分片操作、塊拆分和遷移、添加刪除分片等。例如塊拆分信息:
db.getCollection('changelog').find({"what":/split/}).sort({"time":-1}).limit(2)
每次數據庫塊移動都會創建插入4條記錄到changelog文檔總,分別是start、commit、from、to
{ "_id" : "backup-2018-04-09T15:52:26.656+0800-5acb1bbaebfa528b3521327c", "server" : "backup", "clientAddr" : "192.168.137.30:53996", "time" : ISODate("2018-04-09T07:52:26.656Z"), "what" : "moveChunk.start", "ns" : "test.person", "details" : { "min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : 1.0 }, "from" : "rs-b", "to" : "rs-a" } } /* 2 */ { "_id" : "backup-2018-04-09T15:52:29.289+0800-5acb1bbdebfa528b35213335", "server" : "backup", "clientAddr" : "192.168.137.30:53996", "time" : ISODate("2018-04-09T07:52:29.289Z"), "what" : "moveChunk.commit", "ns" : "test.person", "details" : { "min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : 1.0 }, "from" : "rs-b", "to" : "rs-a" } } /* 3 */ { "_id" : "backup-2018-04-09T15:52:29.297+0800-5acb1bbdebfa528b3521333a", "server" : "backup", "clientAddr" : "192.168.137.30:53996", "time" : ISODate("2018-04-09T07:52:29.297Z"), "what" : "moveChunk.from", "ns" : "test.person", "details" : { "min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : 1.0 }, "step 1 of 6" : 0, "step 2 of 6" : 10, "step 3 of 6" : 153, "step 4 of 6" : 2061, "step 5 of 6" : 402, "step 6 of 6" : 24, "to" : "rs-a", "from" : "rs-b", "note" : "success" } } /* 4 */ { "_id" : "master-2018-04-09T15:52:29.307+0800-5acb1bbd7bc60438ea626411", "server" : "master", "clientAddr" : "", "time" : ISODate("2018-04-09T07:52:29.307Z"), "what" : "moveChunk.to", "ns" : "test.person", "details" : { "min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : 1.0 }, "step 1 of 6" : 22, "step 2 of 6" : 11, "step 3 of 6" : 4, "step 4 of 6" : 0, "step 5 of 6" : 2042, "step 6 of 6" : 373, "note" : "success" } }
View Code
details字段中的每一步表示的都是時間,"step N of 6"信息以毫秒為單位顯示步驟耗時的長短。
當from分片收到mongos發來的moveChunks命令時,它會做如下操作:
(1).檢查命令參數;
(2)向配置服務器申請獲得一個分布鎖,以便進入遷移過程;
(3)嘗試連接到to分片;
(4)復制數據
(5)與to分片和配置服務器一起確認遷移是否成功完成。
當to分片收到from分片發來的命令時,它會執行如下操作:
(1)遷移索引;
(2)刪除塊范圍內已經存在的任何數據;
(3)將塊中的所有文檔復制到to分片;
(4)在to分片上運行復制期間對這些文檔所執行過的操作;
(5)等待to分片將遷移過來的數據復制到副本集的大多數服務器上。
(6)標志遷移是否執行成功。
chunks
存儲集合分片所有塊信息
collections
記錄所有分片集合信息,該記錄中的記錄不會因為分片集合被刪除而被清除。
databases
記錄集群中數據庫的信息,不管數據庫有沒有分片。如數據庫開啟了分片,那么"partitioned" :字段的值為true。"primary"記錄數據庫所屬的主分片。所有新集合默認創建在數據庫主分片上。比如當前的集合在某個分片上面還沒有數據那么不會在該分片上創建集合。所以如果某個分片存在分片的集合,那么必須將集合的數據移走或者將集合刪除,否則該分片無法刪除。
lockpings
記錄分片運行是否正常的ping記錄信息
locks
記錄存儲分布式鎖操作信息。
migrations
mongos
記錄mongos的相關信息,記錄每一個mongos實例的信息。
settings
包含平衡器和塊的設置信息等。
shards
群集分片信息
tags
記錄分片標簽信息
transactions
version
群集版本信息
注意:如果需要修改配置信息,需要通過連接到mongos切換到config數據庫操作而不是直接連接到配置服務器中操作。
參考:https://docs.mongodb.com/manual/reference/config-database/
db.adminCommand({"connPoolStats":1})
mongos可以接受的最大并發連接數。如果此設置高于操作系統配置的最大連接跟蹤閾值,則此設置無效。
注意:在版本2.6中MongoDB刪除了maxIncomingConnections 設置的上限。
use admin db.auth("dba","dba") sh.addShard("rs-a/192.168.137.10:27010,192.168.137.10:27011,192.168.137.10:27012"); sh.addShard("rs-b/192.168.137.20:28010,192.168.137.20:28011,192.168.137.20:28012"); sh.addShard("rs-c/192.168.137.30:26010,192.168.137.30:26011,192.168.137.30:26012"); sh.status();
先當前分片對應數據庫挪到其它的分片上。這里的"products"指的是數據庫名
db.runCommand( { movePrimary: "products", to: "rs-b" })
然后再刪除分片
db.runCommand({"removeShard":"rs-c"});
注意:需要多次執行db.runCommand({"removeShard":"rs-c"});命令來刪除分片,首先平衡器會將分片上的數據進行遷移,可以通過sh.isBalancerRunning()命令查詢是否遷移完成,遷移完成之后再次執行刪除分片命令徹底移除分片。
3.1開啟平衡器
use admin sh.startBalancer() 或者 sh.setBalancerState(true)
3.2關閉平衡器
use admin sh.stopBalancer() 或者 sh.setBalancerState(false);
查看是否關閉,返回flase標識平衡器已關閉,還需要查詢均衡器正在運行情況
sh.getBalancerState(); while( sh.isBalancerRunning() ) { print("waiting..."); sleep(1000); }
在執行數據庫管理操作之前應該關閉平衡器,關閉平衡器之后,系統不會再進入平衡過程, 但是均衡器的關閉不是立即就完成,所以還需要查詢均衡器是否正在運行.
3.3查看平衡器開啟狀態
db.settings.find({"_id":"balancer"}) 或者 sh.getBalancerState()
3.4查看平衡器是否在運行
返回ture代表正在運行,false代表當前沒有在運行。
3.5指定平衡時間
必須先保證平衡器是開啟狀態
use config sh.setBalancerState( true ) db.settings.update({"_id":"balancer"}, {"$set":{"activeWindows":{"start":"13:00","stop":"16:00"}}}, {upsert:true} )
For HH values, use hour values ranging from 00 - 23.
For MM value, use minute values ranging from 00 - 59.
3.6關閉平衡時間
use config db.settings.update({ _id : "balancer" }, { $unset : { activeWindows : true } })
3.7關閉開啟指定文檔的平衡器
關閉
sh.disableBalancing("test.aa")
開啟
sh.enableBalancing("test.aa")
查詢是否關閉文檔的平衡器,返回true代表關閉。沒有結果返回沒有關閉,返回報錯代表文檔不存在或者文檔沒有開啟分片
db.getSiblingDB("config").collections.findOne({_id : "test.aa"}).noBalance;
3.8.備份時注意事項
在執行備份前需要關閉平衡器,但是均衡器的關閉不是立即就完成,所以還需要查詢均衡器是否正在運行,不要在平衡器處于活動狀態時備份,可以備份操作前執行以下查詢:
sh.getBalancerState() sh.isBalancerRunning()
注意:保證平衡器處于關閉狀態同時sh.isBalancerRunning()返回的不是ture ;也可以通過設置平衡器的平衡時間來維護備份。
參考:https://docs.mongodb.com/manual/tutorial/manage-sharded-cluster-balancer/
單位MB,默認塊大小為64MB。塊越大遷移至分片的耗時就越長。
use config; 查詢當前塊大小 db.settings.find({"_id":"chunksize"}) 修改塊大小 db.settings.save( { _id:"chunksize", value: 64 } );
2.1查詢文檔塊信息
db.getCollection('chunks').find({"ns":"test.xxxx"})
2.2將塊"$minKey"移動到分片rs-c上
移動塊只需要指定塊的返回內的隨便一個值即可,注意塊的范圍不包含上限。
sh.moveChunk("test.xxxx",{"username":"$minKey"},"rs-c")
2.3拆分塊
如果塊的大小超過setting設置的最大塊大小時,系統會禁止移動塊,這時候需要將塊進行拆分。這里需要指定新的塊范圍,指定下限即可。
sh.splitAt("test.xxxx",{ "username" :"p" })
2.4查詢塊的大小
db.runCommand({ dataSize: "test.xxxx", keyPattern: { "username": 1 }, min: { "username" : "b" }, max: { "username" : "c" } })
單位字節,需要指定塊的范圍。
2.5無法拆分的特大塊處理
假設使用year/month/day字段作為分片,某一天業務遭受攻擊導致這天的數據量暴增,但是由于分片的值已經的最小單位了無法再拆分了,這個時候通過塊拆分已經無法解決問題,可以手動將塊移動到非熱點的分片上。
mongos有時無法從配置服務器正確更新配置信息,可以使用flushRouterConfig命令手動刷新緩存,如果刷新還無法解決需要重啟mongos進程。
db.adminCommand({"flushRouterConfig":1})
use news db.dropDatabase()
上述內容就是MongoDB中怎么實現分片管理,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。