鍍金池/ 問答/數(shù)據(jù)庫(kù)/ mongodb備份結(jié)點(diǎn)數(shù)據(jù)目錄與主結(jié)點(diǎn)數(shù)據(jù)大小不一致

mongodb備份結(jié)點(diǎn)數(shù)據(jù)目錄與主結(jié)點(diǎn)數(shù)據(jù)大小不一致

求大神解惑:
兩個(gè)mongodb結(jié)點(diǎn),主備模式,查看兩個(gè)結(jié)點(diǎn)下的數(shù)據(jù)目錄發(fā)現(xiàn):
主結(jié)點(diǎn)data目錄的為23GB,目錄詳情如下:
clipboard.png

備份結(jié)點(diǎn)data目錄為11GB,錄詳情如下:
clipboard.png

db.collection.stats()數(shù)據(jù)量是一致的,請(qǐng)問這是什么原因?是否有相關(guān)的資源可以查閱?

回答
編輯回答
故人嘆

題外話,MongoDB歷史上出現(xiàn)過master/slave復(fù)制(其實(shí)現(xiàn)在也還存在)。嚴(yán)格地說,主備通常指的是那個(gè)東西。而我們現(xiàn)在用的基本上是復(fù)制集(replica set)。

再說你這種情況,其實(shí)是正常的。原理跟你的磁盤用久了會(huì)有碎片是一個(gè)道理。特別是你曾經(jīng)大規(guī)模刪除過數(shù)據(jù)的情況下。簡(jiǎn)單地解釋下,假設(shè)你的表中有doc1/doc2/doc3/doc4一共4個(gè)文檔,在磁盤上的存儲(chǔ)順序是:
doc1|doc2|doc3|doc4
現(xiàn)在你刪除了doc2,磁盤上的空間使用情況變成:
doc1|(空白)|doc3|doc4
系統(tǒng)是沒有辦法釋放這個(gè)空白空間的,除非你進(jìn)行磁盤整理,把空白空間移到最后:
doc1|doc3|doc4|(空白)
然后系統(tǒng)才可以截?cái)辔募膊康目瞻祝尫诺暨@個(gè)空間??梢钥闯鰜?,要把空白移動(dòng)到文件尾是個(gè)相當(dāng)費(fèi)時(shí)費(fèi)力的操作,最簡(jiǎn)單的辦法是:把后面所有的文檔順序前移來填補(bǔ)doc2留下的空白(如上所示doc3/doc4被前移)。但是這樣涉及到大量的磁盤I/O,會(huì)對(duì)性能造成嚴(yán)重影響。當(dāng)然不乏其他整理磁盤碎片的方法,但是無論哪一個(gè),都會(huì)造成比較嚴(yán)重的I/O影響,因此一般我們是不會(huì)進(jìn)行這樣的整理的。進(jìn)行碎片整理的方式就是:compact命令。如前所述,因?yàn)樗鼤?huì)對(duì)性能造成嚴(yán)重的影響,因此一般只會(huì)在維護(hù)時(shí)間進(jìn)行這個(gè)操作。而就算你不進(jìn)行這個(gè)操作,系統(tǒng)也知道哪些地方是空白的,在有新文檔進(jìn)來的時(shí)候,會(huì)嘗試重新使用這些空白的部分從而最大化空間利用率。只是,無論再好的算法,空間重復(fù)利用一定不可能是100%的,因?yàn)樾逻M(jìn)來的文檔永遠(yuǎn)沒有辦法正好跟之前被刪除的文檔一樣大,所以只能找一個(gè)比新文檔更大的空間來利用,這樣就會(huì)留下一個(gè)更小的、更難重復(fù)利用的碎片。
另外一種變通的方案是把節(jié)點(diǎn)內(nèi)容刪除,重新進(jìn)行一次同步。因?yàn)橥綍r(shí)相當(dāng)于把所有文檔全部抓取一遍,并一個(gè)接一個(gè)重新寫到磁盤上,因此同步完成之后文檔在磁盤上是緊湊排列的,相當(dāng)于進(jìn)行了碎片整理。而且在這個(gè)過程中,受影響的是從節(jié)點(diǎn),它在同步過程中并不對(duì)外提供服務(wù),所以對(duì)線上的影響是最小的。但是注意,它同樣會(huì)對(duì)主節(jié)點(diǎn)造成影響,因?yàn)樗阎鞴?jié)點(diǎn)上的全部數(shù)據(jù)都讀一遍,主節(jié)點(diǎn)I/O升高是無法避免的。

最后回到你的問題,為什么從節(jié)點(diǎn)比主節(jié)點(diǎn)小,上面應(yīng)該已經(jīng)解釋清楚了。

2017年10月23日 22:14