1007
技術社區[雲棲]
MongoDB 哈希分片為什麼數據大小不均勻?
今天接到一個用戶反饋的問題,sharding集群,使用wiredtiger引擎,某個DB下集合全部用的hash分片,show dbs
發現其中一個shard裏該DB的大小,跟其他的集合差別很大,其他基本在60G左右,而這個shard在200G左右?
由於這個DB下有大量的集合及索引,一眼也看不出問題,寫了個腳本分析了一下,得到如下結論
- somedb 下所有集合都是hash分片,並且chunk的分布是比較均勻的
- show dbs 反應的是集合及索引對應的物理文件大小
- 集合的數據在各個shard上邏輯總大小是接近的,隻有shard0占用的物理空間比其他大很多
從shard0上能找到大量 moveChunk 的記錄,猜測應該是集合的數據在沒有開啟分片的情況下寫到shard0了,然後開啟分片後,從shard0遷移到其他shard了,跟用戶確認的確有一批集合是最開始沒有分片。
所以這個問題就轉換成了,為什麼複製集裏集合的邏輯空間與物理空間不一致?即collection stat 裏 size
與 storageSize
的區別。
mymongo:PRIMARY> db.coll.stats()
{
"ns" : "test.coll",
"size" : 30526664,
"count" : 500808,
"avgObjSize" : 33,
"storageSize" : 19521536,
"capped" : false,
....
}
邏輯存儲空間與物理存儲空間有差距的主要原因
- 存儲引擎存儲時,需要記錄一些額外的元數據信息,這會導致物理空間總和比邏輯空間略大
- 存儲引擎可能支持數據壓縮,邏輯的數據塊存儲到磁盤時,經過壓縮可能比邏輯數據小很多了(具體要看數據的特性,極端情況下壓縮後數據變大也是有可能的)
- 引擎對刪除空間的處理,很多存儲引擎在刪除數據時,考慮到效率,都不會立即去挪動數據回收刪除的存儲空間,這樣可能導致刪除很多文檔後,邏輯空間變小,但物理空間並沒有變小。如下圖所示,灰色的文檔刪除表示被刪除。刪除的空間產生很多存儲碎片,這些碎片空間不會立即被回收,但有新文檔寫入時,可以立即被複用。
而上述case裏,集合數據先分到一個shard,然後啟用分片後,遷移一部分到其他shard,就是一個典型的產生大量存儲碎片的例子。存儲碎片對服務通常影響不大,但如果因為空間不夠用了需要回收,如何去強製的回收這些碎片空間?
- 數據清理掉重新加入複製集同步數據,或者直接執行resync命令 (確保有還有其他的數據備份)
- 對集合調用 compact 命令
2017-08-03 15:42:04 update
關於 compact操作,有同學問道,問題鏈接
mongdb中由於刪除了大量的數據,但是沒有釋放磁盤空間給係統,想通過compact命令來釋放磁盤空間;但是對compact命令有幾個疑問
1. compact命令在WiredTiger引擎上是庫級別鎖還是collection級別鎖?
2. 執行compact命令需要多大的空餘磁盤空間呢
- compact 加的是DB級別的互斥寫鎖,同一個DB上的讀寫都會被阻塞
- compact基本不需要額外的空間,wiredtiger compact的原理是將數據不斷往前麵的空洞挪動,並不需要把數據存儲到臨時的位置(額外的存儲空間)。
參考資料
最後更新:2017-08-13 22:40:22
上一篇:
plpgsql 編程 - JSON數組循環
下一篇:
此情可待成追憶,卷積通俗容易記(深度學習入門係列之十)
Mysql innodb存儲引擎體係架構
《雲數據管理:挑戰與機遇》2.3.2 並發控製
2017年ACL的四個NLP深度學習趨勢 (一):語言結構和詞匯嵌入(Linguistic Structure and Word Embeddings)
Java Generic Deep Copy
事務必會必知
System.BadImageFormatException: 未能加載文件或程序集“Oracle.DataAccess”或它的某一個依賴項。試圖加載格式不正確的程序。
Javascript 學習 筆記一
Linux常用命令大全 Linux Commands Line - v1.0
從一道麵試題分析Linux進程+IO緩衝區機製
常用Maven插件介紹(上)