天天看點

MongoDB 哈希分片為什麼資料大小不均勻?

今天接到一個使用者回報的問題,sharding叢集,使用wiredtiger引擎,某個db下集合全部用的hash分片,<code>show dbs</code> 發現其中一個shard裡該db的大小,跟其他的集合差别很大,其他基本在60g左右,而這個shard在200g左右?

MongoDB 哈希分片為什麼資料大小不均勻?

由于這個db下有大量的集合及索引,一眼也看不出問題,寫了個腳本分析了一下,得到如下結論

somedb 下所有集合都是hash分片,并且chunk的分布是比較均勻的

show dbs 反應的是集合及索引對應的實體檔案大小

集合的資料在各個shard上邏輯總大小是接近的,隻有shard0占用的實體空間比其他大很多

從shard0上能找到大量 movechunk 的記錄,猜測應該是集合的資料在沒有開啟分片的情況下寫到shard0了,然後開啟分片後,從shard0遷移到其他shard了,跟使用者确認的确有一批集合是最開始沒有分片。

是以這個問題就轉換成了,為什麼複制集裡集合的邏輯空間與實體空間不一緻?即collection stat 裡 <code>size</code> 與 <code>storagesize</code> 的差別。

邏輯存儲空間與實體存儲空間有差距的主要原因

存儲引擎存儲時,需要記錄一些額外的中繼資料資訊,這會導緻實體空間總和比邏輯空間略大

存儲引擎可能支援資料壓縮,邏輯的資料塊存儲到磁盤時,經過壓縮可能比邏輯資料小很多了(具體要看資料的特性,極端情況下壓縮後資料變大也是有可能的)

引擎對删除空間的處理,很多存儲引擎在删除資料時,考慮到效率,都不會立即去挪動資料回收删除的存儲空間,這樣可能導緻删除很多文檔後,邏輯空間變小,但實體空間并沒有變小。如下圖所示,灰色的文檔删除表示被删除。删除的空間産生很多存儲碎片,這些碎片空間不會立即被回收,但有新文檔寫入時,可以立即被複用。

MongoDB 哈希分片為什麼資料大小不均勻?

而上述case裡,集合資料先分到一個shard,然後啟用分片後,遷移一部分到其他shard,就是一個典型的産生大量存儲碎片的例子。存儲碎片對服務通常影響不大,但如果因為空間不夠用了需要回收,如何去強制的回收這些碎片空間?

資料清理掉重新加入複制集同步資料,或者直接執行resync指令 (確定有還有其他的資料備份)

對集合調用 compact 指令

2017-08-03 15:42:04 update

mongdb中由于删除了大量的資料,但是沒有釋放磁盤空間給系統,想通過compact指令來釋放磁盤空間;但是對compact指令有幾個疑問

compact指令在wiredtiger引擎上是庫級别鎖還是collection級别鎖?

執行compact指令需要多大的空餘磁盤空間呢

compact 加的是db級别的互斥寫鎖,同一個db上的讀寫都會被阻塞

compact基本不需要額外的空間,wiredtiger compact的原理是将資料不斷往前面的空洞挪動,并不需要把資料存儲到臨時的位置(額外的存儲空間)。

<a href="https://docs.mongodb.com/manual/tutorial/resync-replica-set-member/">resync指令</a>

<a href="https://yq.aliyun.com/articles/new?spm=5176.8091938.0.0.8ldnnt">compact指令</a>

<a href="https://www.aliyun.com/product/mongodb">雲資料庫mongodb版</a>