如何加快 MongoDB 塊在分片之間的移動
在副本集和 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 天。
如果你嘗試這個,請確保你有一個備份,以防出現問題。
這是程序:
- 計算要移動的記錄(在分片 rs0 上)
db.use.find({$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]}).count()
- 將樣本轉儲到分片 rs0
mongodump --host <rs0-host> --db=db --collection=use --archive --gzip --query '{$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]}' > dump.gz
- 刪除shard rs0上的數據(直接連接rs0 mongod,不通過mongos)
db.use.deleteMany({$and:[{_id:{$gt: ObjectId("58B60F00e4b03547ad945a8a")}}, {_id: {$lt: ObjectId("58BCA680e4b03547ad945a8a")}}]})
- 移動塊(連接到 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)
- 恢復轉儲(連接到 mongos)
mongorestore --host <mongos> --db=db --collection=use --gzip --archive=dump.gz