1. 手動切割chunk主要是兩個函數(shù)splitAt(fullname,middle)與splitFind(fullname,find). fullname指定哪個庫的哪個集合。middle與find都是條件,代表你想手動切割哪個chunk. 需要注意的是條件必須包含片鍵,不然報錯,如下圖。 這兩個函數(shù)不同的是: 1.1 spli
1. 手動切割chunk主要是兩個函數(shù)splitat(fullname,middle)與splitfind(fullname,find). fullname指定哪個庫的哪個集合。middle與find都是條件,代表你想手動切割哪個chunk. 需要注意的是條件必須包含片鍵,不然報錯,如下圖。
這兩個函數(shù)不同的是:
1.1 splitAt利用middle這個條件找到對應的chunk,并以這個條件所查詢到的第一條結果為分隔點,把原先的chunk分隔成兩部分。
(一)在手動切隔之前,sar總共有三個塊。如下圖
(二)執(zhí)行切割命令
之后chunks的分布如下圖
可以看出,執(zhí)行之后,將第二個chunk,香港虛擬主機,按照{(diào)_id:ObjectId(“50dc0790525e4314024b79d0”)}這個值為分隔點分隔成第2,3兩塊。
1.2 函數(shù)splitFind,官網(wǎng)解釋是將找到的第一個chunk分隔成size大小相等的兩個chunk.但是我在測試過程中發(fā)現(xiàn)并不是這么回事。版本是2.2.2
(一)準備數(shù)據(jù)。向一個新集合插入250W條有規(guī)律的數(shù)據(jù)。如下圖。字段name的值末尾是一個自增的數(shù)字。
(二)數(shù)據(jù)插入之后,集合的分塊情況如下圖。
(三)我們可以看下,第一塊最后一條數(shù)據(jù)是什么。
(四)可以看到,第一塊最后一條數(shù)據(jù)的name值是”habc780335″.也就是說第一塊有78W條數(shù)據(jù)之多。現(xiàn)在將第一塊分成兩塊。使用splitFind()函數(shù)。
(五)name值為”habc19″肯定是在第一塊中。因為按官網(wǎng)所說,應該將第一塊分成size大小相等的兩塊。可實際上呢?
(六)如上圖,的確是將原先的第一塊分成了兩塊。第二塊最后一條的ID值就是原先第一塊最后一條的ID值。但第1,2這兩塊size大小是相等的嗎?如下圖。
(七)如上圖。第一塊的最后一條數(shù)據(jù)實際上就是第一條數(shù)據(jù)。這說明第一塊實際上只有一條數(shù)據(jù)。很顯然這兩塊的size是不相等的。真實情況究竟是什么呢 ???
2. 今天在將一個已被移除的shard重新添加進來的時候,出現(xiàn)了問題。特記錄下來。
問題:將一個shard移除后,我沒有停掉這個shard。后來為了測試我又把它添加進來。db.runCommand({addshard:”hostname:port”}); 操作提示成功。也開始了遷移數(shù)據(jù)。等遷移完成之后,我進行查詢操作,發(fā)現(xiàn)操作失敗。錯誤提示是“gotshardname different than what i had before” 。如下圖
錯誤提示是說,這個shard之前添加進來的時候name被賦值為shard0001,現(xiàn)在再次添加進來后name被賦值為shard0000.當進行查詢操作時發(fā)現(xiàn)這前后name不一樣。所以報錯。我比較困惑的是,它是怎么知道這個shard之前的name值的。我找遍config庫下面的所有collection.都沒有發(fā)現(xiàn)有地方存儲shard之前的name值。僅僅只有shards這個集合存儲相關數(shù)據(jù)。但是存儲的都是此時此刻各個shard的情況。問了渡娘與google.沒有什么收獲。后來沒辦法,我想把這個shard再一次的remove掉后再添加進來。可以不行。
雖然操作提示是成功的,但是過了很久我發(fā)現(xiàn)數(shù)據(jù)根本就沒有遷移。查詢?nèi)罩荆l(fā)現(xiàn)了錯誤提示。
錯誤提示仍是name值前后不一樣。后來在同事的提示下,我將這個shard重啟,重啟后發(fā)現(xiàn)問題解決了。
分析:每個添加進去的shard的name值不僅在config庫存儲,同時各個shard也都存儲著這個值。不同的是,config庫的數(shù)據(jù)是落地的,但各個shard是緩存起來的。被移除的shard如果不重啟,那么這個name值就一直存在。有一點我不理解的是,既然name值存在,并且再次添加后name不一樣卻能添加成功,并且數(shù)據(jù)也都遷移過來了,香港虛擬主機,只是查詢操作的時候才報錯。難道遷移數(shù)據(jù)與查詢數(shù)據(jù)使用的是不同地方的name值? 有一點需要注意的是,雖然查詢操作失敗,但寫操作能夠成功。
如何避免:db.runCommand({addshard:”hostname:port”,name:”xxx”}) VS db,runCommand({addshard:”hostname:port”})。 在addshard的時候,我沒有指定name值,系統(tǒng)就使用默認值從shard0000開始遞增。因此,在addshard時一定要手動指定name值。
?
?
?
?
,服務器空間