1. 程式人生 > >MongoDB雜湊分片為什麼分佈不均勻?

MongoDB雜湊分片為什麼分佈不均勻?

原文地址

今天接到一個使用者反饋的問題,sharding叢集,使用wiredtiger引擎,某個DB下集合全部用的hash分片,show dbs 發現其中一個shard裡該DB的大小,跟其他的集合差別很大,其他基本在60G左右,而這個shard在200G左右?

_2017_08_02_7_31_54

由於這個DB下有大量的集合及索引,一眼也看不出問題,寫了個指令碼分析了一下,得到如下結論

  1. somedb 下所有集合都是hash分片,並且chunk的分佈是比較均勻的
  2. show dbs 反應的是集合及索引對應的物理檔案大小
  3. 集合的資料在各個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,
    ....
}

邏輯儲存空間與物理儲存空間有差距的主要原因

  1. 儲存引擎儲存時,需要記錄一些額外的元資料資訊,這會導致物理空間總和比邏輯空間略大
  2. 儲存引擎可能支援資料壓縮,邏輯的資料塊儲存到磁碟時,經過壓縮可能比邏輯資料小很多了(具體要看資料的特性,極端情況下壓縮後資料變大也是有可能的)
  3. 引擎對刪除空間的處理,很多儲存引擎在刪除資料時,考慮到效率,都不會立即去挪動資料回收刪除的儲存空間,這樣可能導致刪除很多文件後,邏輯空間變小,但物理空間並沒有變小。如下圖所示,灰色的文件刪除表示被刪除。刪除的空間產生很多儲存碎片,這些碎片空間不會立即被回收,但有新文件寫入時,可以立即被複用。

_2017_08_02_8_03_44

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

  • 資料清理掉重新加入複製集同步資料,或者直接執行resync命令 (確保有還有其他的資料備份)
  • 對集合呼叫 compact 命令

參考資料


原文地址