Мы создали кластер MongoDB с 2-мя шардами (наборы реплик), каждый из которых содержит основной и дополнительный узлы.После переноса данных в кластер с помощью mongorestore
, включения сегментирования как на уровне базы данных, так и на уровне коллекции и ожидания, пока балансировщик не разделит коллекцию на 2 сегмента, возникла проблема, заключающаяся в том, что все данные остаются полностью в источнике.набор реплик, в то время как половина из них была перенесена в набор реплик назначения без проблем.
Наш кластер построен с использованием Docker Swarm с такой архитектурой:
rs1
(1 основнойrs11
, 1 дополнительный rs12
); rs2
(1 основной rs21
, 1 дополнительный rs22
); cfg0
(1 сервер конфигурации); mongos0
router.
После завершения установки мы попытались восстановить дамп из нашей старой базы данных через mongodump
/ mongorestore
с успехом - mongos0
восстановили коллекцию ок.2B
записей в rs2
и реплицируются между его узлами.
Мы создали индекс по полю timestamp
:
db.records.createIndex({ timestamp: 'hashed' })
После этого мы включили сегментирование коллекции:
db.shardCollection("sample.records", { timestamp: 'hashed' })
... и включенный балансировщик:
sh.startBalancer()
Через некоторое время мы добились успеха с успехом:
shard key: { "timestamp" : "hashed" }
unique: false
balancing: true
chunks:
rs1 14029
rs2 14030
НО мы ожидалиданные будут распределены по этим 2 осколкам, и половина пространства из rs2
будет освобождена, но мы не знаем, как освободить дисковое пространство от существующего rs2
.Резюме, эта проблема видна ниже:
>> db.stats(1024*1024*1024) # show size in GiB
...
"raw" : {
"rs1/mongors11:27017,mongors12:27017" : {
"db" : "sample",
"collections" : 1,
"views" : 0,
"objects" : 1215894909,
"avgObjSize" : 393.2806568671964,
"dataSize" : 445.3472313405946,
"storageSize" : 131.5478172302246,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 19.27316665649414,
"fsUsedSize" : 184.22602081298828,
"fsTotalSize" : 411.00279235839844,
"ok" : 1
},
"rs2/mongors21:27017,mongors22:27017" : {
"db" : "sample",
"collections" : 11,
"views" : 0,
"objects" : 2308125918,
"avgObjSize" : 387.33301163381327,
"dataSize" : 832.6148270154372,
"storageSize" : 274.2057418823242,
"numExtents" : 0,
"indexes" : 19,
"indexSize" : 40.794044494628906,
"fsUsedSize" : 348.7571792602539,
"fsTotalSize" : 411.00279235839844,
"ok" : 1
}
РЕДАКТИРОВАТЬ : дополнительная информация о статистике сбора по кластеру:
>> db.records.stats()['shards']
...
"rs1" : {
"ns" : "sample.records",
"size" : 478187948493,
"count" : 1215894909,
"avgObjSize" : 393,
"storageSize" : 141248393216,
"capped" : false
}
...
"rs2" : {
"ns" : "sample.records",
"size" : 894011940704,
"count" : 2308120195,
"avgObjSize" : 387,
"storageSize" : 294425526272,
"capped" : false
}
Посмотрите на rs2
осколокОн содержит все данные без освобождения дискового пространства после того, как половина данных перенесена в rs1
.
Сводка, у нас возникла проблема: 1/2
всей коллекции - на rs1
и 2/2
Как освободить дисковое пространство на rs2
, чтобы они содержали только половину данных, точно так же как rs1
?