Performance

如何加快 MongoDB 塊在分片之間的移動

  • February 11, 2022

在副本集和 WiredTiger 引擎中的 MongoDB 3.6 上,我們有一個包含 7.7TB 數據的大型集合。我們開始看到嚴重的性能問題(極端的 CPU 使用率和數據複製速度變慢),我們通過臨時使用新的空數據庫以某種方式解決了這些問題。數據基本上是使用日誌,而數據庫模式主要是插入(新使用數據),偶爾會為某些使用者或報告讀取數據。

從長遠來看,為了擴展系統並解決性能問題,我們現在創建了兩個分片,其中的想法是擁有一個快速分片(包含最近 2 個月的數據)和一個慢速分片(包含所有歷史數據)。快速分片在具有 的n1-standard-8 (8 vCPUs, 30 GB memory)機器上執行SSD disks,而慢速分片在n1-highmem-2 (2 vCPUs, 13 GB memory)具有rotational disks.

數據庫沒有任何負載(沒有新的使用日誌插入)並且基本上什麼都不做。分片過程已經開始,但是移動塊的速度很慢,大約需要 40 天才能移動所有塊。剩下 200000 個塊要從分片移動到慢速分片,平均塊大小為 32MB,移動一個塊大約需要 18 秒。

可以做些什麼來加快這個塊遷移過程?

更新

我了解到,如果源分片在 SSD 磁碟上,那麼塊移動的速度幾乎是兩倍。

比如我們有多少分片,分片的數據庫,以及分片集群的配置設置。但是配置伺服器擁有的最重要的資訊之一是塊到分片的映射。

By default MongoDB takes ChunkSize=64 MB

預設情況下,MongoDB 將 64 兆字節作為預設塊大小。這意味著如果一個塊大約為 64 兆字節,或者在 64 兆噸範圍內,它將被拆分。

1MB<=chunkSize<=1024MB

我們可以在 1 MB 和 1024 和 1 GB 的值之間定義塊大小。塊大小在執行時是可配置的。所以如果我們決定改變一個塊的大小,我們可以很容易地做到這一點。但在我們改變你的塊大小之前。

進一步參考這里這裡

最後,我找到了另一種加快塊移動的方法。這是我在數據集的一小部分(8000 萬條記錄)上嘗試的過程,估計這樣整個遷移大約需要 16 天。

如果你嘗試這個,請確保你有一個備份,以防出現問題。

這是程序:

  1. 計算要移動的記錄(在分片 rs0 上)
db.use.find({$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]}).count()
  1. 將樣本轉儲到分片 rs0
mongodump --host <rs0-host> --db=db --collection=use --archive --gzip --query '{$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]}' > dump.gz
  1. 刪除shard rs0上的數據(直接連接rs0 mongod,不通過mongos)
db.use.deleteMany({$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]})
  1. 移動塊(連接到 mongos)
use config
sh.stopBalancer()
var lower=ObjectId("58B60F00e4b03547ad945a8a");
var upper=ObjectId("58BCA680e4b03547ad945a8a");
var query={shard: "rs0", ns: "db.use", "max._id":{$gte: lower}, "min._id": {$lte: upper}};
var cursor=db.chunks.find(query);

cursor.forEach(function(d) {
 print( "chunk: " + d.min._id ); 
 sh.moveChunk("db.use", { "_id" : d.min._id }, "rs1");
});
sh.setBalancerState(true)
  1. 恢復轉儲(連接到 mongos)
mongorestore --host <mongos> --db=db --collection=use --gzip --archive=dump.gz

引用自:https://dba.stackexchange.com/questions/203383