Das Ziel dieses Beitrags ist es, die verschiedenen Möglichkeiten der Datenmigration in MongoDB kennenzulernen, die uns helfen können, Skripte zu schreiben, die Ihre Datenbank ändern, indem neue Dokumente hinzugefügt und vorhandene geändert werden.
Wenn Sie zum ersten Mal hierher kommen, werfen Sie bitte einen Blick auf das Prequel Self-Hosted MongoDB.
In Ordnung, beginnen wir dort, wo wir aufgehört haben, und beginnen wir mit der Datenmigration in MongoDB.
Die grundlegenden Schritte zum Migrieren von Daten von einer MongoDB zu einer anderen wären nun:
- Erstellen Sie eine gezippte Sicherung der vorhandenen Daten
- Speichere die Daten in einer neuen DB
Dies ist sehr einfach, wenn die Quelldatenbank nicht online ist, da wir wissen, dass während des Migrationsprozesses keine neuen Dokumente erstellt/aktualisiert werden. Schauen wir uns zuerst die einfache Migration an, bevor wir in das Live-Szenario eintauchen.
Migration von einer Offline-Datenbank in MongoDB
Erstellen einer Sicherung
Wir werden ein vorhandenes Hilfsprogramm mongodump zum Erstellen der Datenbanksicherung verwenden.
Führen Sie diesen Befehl auf dem Quelldatenbankserver
ausmongodump --host="hostname:port" \
--username="username" --password="password" \
--authenticationDatabase "admin" \
--db="db name" --collection="collection name" --query='json' \
--forceTableScan -v --gzip --out ./dump
--host
:Der Quell-MongoDB-Hostname zusammen mit dem Port. Der Standardwert ist localhost:27017
. Wenn es sich um eine Verbindungszeichenfolge handelt, können Sie diese Option verwenden —-uri="mongodb://username:password@host1[:port1]..."
--username
:Gibt einen Benutzernamen an, um sich bei einer MongoDB-Datenbank zu authentifizieren, die Authentifizierung verwendet.
--password
:Gibt ein Passwort zur Authentifizierung bei einer MongoDB-Datenbank an, die Authentifizierung verwendet.
--authenticationDatabase
:Gibt die Authentifizierungsdatenbank an, in der der angegebene --username
wurde erstellt.
Wenn Sie keine Authentifizierungsdatenbank oder eine zu exportierende Datenbank angeben, geht mongodump davon aus, dass die Admin-Datenbank die Anmeldeinformationen des Benutzers enthält.
--db
:Gibt die Datenbank an, von der eine Sicherung erstellt werden soll. Wenn Sie keine Datenbank angeben, sammelt mongodump von allen Datenbanken in dieser Instanz.
Alternativ können Sie die Datenbank auch direkt in der URI-Verbindungszeichenfolge angeben, z. B. mongodb://username:password@uri/dbname
.
Bereitstellung einer Verbindungszeichenfolge bei gleichzeitiger Verwendung von --db
und die Angabe widersprüchlicher Informationen führt zu einem Fehler .
--collection
:Gibt eine zu sichernde Sammlung an. Wenn Sie keine Sammlung angeben, kopiert diese Option alle Sammlungen in der angegebenen Datenbank oder Instanz in die Dump-Dateien.
--query
:Stellt ein JSON-Dokument als Abfrage bereit, die optional die in der Ausgabe von mongodump enthaltenen Dokumente einschränkt.
Sie müssen das Abfragedokument in einfache Anführungszeichen setzen ('{ ... }')
um sicherzustellen, dass sie nicht mit Ihrer Umgebung interagiert.
Die Abfrage muss im Extended JSON v2-Format (entweder entspannter oder kanonischer/strikter Modus) vorliegen, einschließlich der Feldnamen und Operatoren in Anführungszeichen, z. '{ "created_at": { "\$gte": ISODate(...) } }'
.
Um die --query
zu verwenden müssen Sie auch die --collection
angeben Option.
--forceTableScan
:Zwingt mongodump, den Datenspeicher direkt zu scannen. Normalerweise speichert mongodump Einträge so, wie sie im Index der _id
erscheinen Feld.
Wenn Sie eine Abfrage angeben --query
, verwendet mongodump den am besten geeigneten Index, um diese Abfrage zu unterstützen.
Daher können Sie --forceTableScan
nicht verwenden mit der --query
Möglichkeit .
--gzip
:Komprimiert die Ausgabe. Wenn mongodump in das Dump-Verzeichnis ausgibt, komprimiert das neue Feature die einzelnen Dateien. Die Dateien haben die Endung .gz
.
--out
:Gibt das Verzeichnis an, in das mongodump BSON
schreiben wird Dateien für die gedumpten Datenbanken. Standardmäßig speichert mongodump Ausgabedateien in einem Verzeichnis namens dump im aktuellen Arbeitsverzeichnis.
Wiederherstellung der Sicherung
Wir werden ein Dienstprogramm namens mongorestore
verwenden zum Wiederherstellen der Datenbanksicherung.
Kopieren Sie den Sicherungsverzeichnis-Dump in die neue Datenbankinstanz und führen Sie den folgenden Befehl aus:
mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
--drop --noIndexRestore --gzip -v ./dump
Ersetzen Sie die Anmeldeinformationen durch die neuen Datenbank-Anmeldeinformationen. Trennen Sie im vorherigen Schritt die --authenticationDatabase
Option wird in der URI-Zeichenfolge angegeben.
Verwenden Sie auch --gzip
wenn es beim Erstellen des Backups verwendet wird.
--drop
:Löscht vor dem Wiederherstellen der Sammlungen aus der erstellten Sicherung die Sammlungen aus der Zieldatenbank. Sammlungen, die sich nicht in der Sicherung befinden, werden nicht gelöscht.--noIndexRestore
:Verhindert, dass Mongorestore Indizes wie in der entsprechenden Mongodump-Ausgabe angegeben wiederherstellt und erstellt.
Wenn Sie den Namen der Datenbank während der Wiederherstellung ändern möchten, können Sie dies mit --nsFrom="old_name.*" --nsTo="new_name.*"
tun Optionen.
Es funktioniert jedoch nicht, wenn Sie mit oplogs
migrieren Dies ist eine Voraussetzung für die Migration von einer Online-Instanz.
Migration von einer Online-Datenbank in MongoDB
Die einzige Herausforderung bei der Migration von einer Online-Datenbank besteht darin, dass die Aktualisierungen während der Migration nicht angehalten werden können. Hier ist also die Übersicht der Schritte,
- Führen Sie eine anfängliche Massenmigration mit
oplogs
durch erfassen - Führen Sie einen Synchronisierungsjob aus, um die Latenz beim Datenbankverbindungswechsel zu verringern
Nun zum Erfassen von oplogs
, muss ein Replikatsatz in den Quell- und Zieldatenbanken initialisiert werden. Das liegt daran, dass die oplogs
werden von local.oplog.rs
erfasst Namespace, der nach der Initialisierung eines Replikatsatzes erstellt wird.
Sie können dieser Anleitung folgen, um einen Replikatsatz zu konfigurieren.
Erste Migration mit Oplog Capture
Oplogs sind in einfachen Worten die Vorgangsprotokolle, die pro Vorgang in der Datenbank erstellt werden. Sie repräsentieren einen teilweisen Dokumentzustand oder mit anderen Worten den Datenbankzustand. Wir werden also alle Aktualisierungen in unserer alten Datenbank während des Migrationsprozesses mit diesen oplogs
erfassen .
Führen Sie das Programm mongodump mit den folgenden Optionen aus,
mongodump --uri=".../?authSource=admin" \
--forceTableScan --oplog \
--gzip -v --out ./dump
--oplog
:Erstellt eine Datei namens oplog.bson
als Teil des mongodump
Ausgang. Die oplog.bson
Datei, die sich auf der obersten Ebene des Ausgabeverzeichnisses befindet, enthält oplog
Einträge, die während der Mongodump-Operation auftreten. Diese Datei bietet eine effektive Momentaufnahme des Zustands unserer Datenbankinstanz.
Stellen Sie die Daten mit oplog replay wieder her
Um die Oplogs wiederzugeben, ist eine spezielle Rolle erforderlich. Lassen Sie uns die Rolle erstellen und dem Datenbankbenutzer zuweisen, der für die Migration verwendet wird.
Erstellen Sie die Rolle
db.createRole({
role: "interalUseOnlyOplogRestore",
privileges: [
{
resource: { anyResource: true },
actions: [ "anyAction" ]
}
],
roles: []
})
Weisen Sie die Rolle zu
db.grantRolesToUser(
"admin",
[{ role:"interalUseOnlyOplogRestore", db:"admin" }]
);
Jetzt können Sie mit dem Programm mongorestore mit den folgenden Optionen wiederherstellen,
mongorestore --uri="mongodb://admin:.../?authSource=admin" \
--oplogReplay
--gzip -v ./dump
Verwenden Sie im obigen Befehl denselben Benutzer admin
wem die Rolle zugeordnet war.
--oplogReplay
:Spielt nach dem Wiederherstellen des Datenbank-Dumps die Oplog-Einträge aus einer BSON-Datei ab und stellt die Datenbank in der Point-in-Time-Sicherung wieder her, die mit mongodump --oplog
erfasst wurde Befehl.
Minderung der Latenz beim Datenbankverbindungswechsel
Okay, bis jetzt sind wir mit dem größten Teil des schweren Hebens fertig. Das einzige, was bleibt, ist die Konsistenz zwischen den Datenbanken während des Verbindungswechsels in unseren Anwendungsservern aufrechtzuerhalten.
Wenn Sie MongoDB Version 3.6+ ausführen, ist es besser, sich für den Change Stream-Ansatz zu entscheiden, bei dem es sich um einen ereignisbasierten Mechanismus handelt, der eingeführt wurde, um Änderungen in Ihrer Datenbank auf optimierte Weise zu erfassen. Hier ist ein Artikel, der sich damit befasst https://www.mongodb.com/blog/post/an-introduction-to-change-streams
Sehen Sie sich das generische Synchronisierungsskript an, das Sie jede Minute als CRON-Job ausführen können.
Aktualisieren Sie die Variablen in diesem Skript und führen Sie es aus als
$ ./delta-sync.sh from_epoch_in_milliseconds
# from_epoch_in_milliseconds is automatically picked with every iteration if not supplied
Oder Sie können einen Cron-Job einrichten, um dies jede Minute auszuführen.
* * * * * ~/delta-sync.sh
Die Ausgabe kann mit dem folgenden Befehl überwacht werden (ich verwende RHEL 8, Informationen zur Cron-Ausgabe finden Sie in Ihrem Betriebssystemhandbuch)
$ tail -f /var/log/cron | grep CRON
Dies ist ein Beispiel für ein Synchronisierungsprotokoll.
CMD (~/cron/dsync.sh)
CMDOUT (INFO: Updated log registry to use new timestamp on next run.)
CMDOUT (INFO: Created sync directory: /home/ec2-user/cron/dump/2020-11-03T19:01:01Z)
CMDOUT (Fetching oplog in range [2020-11-03T19:00:01Z - 2020-11-03T19:01:01Z])
CMDOUT (2020-11-03T19:01:02.319+0000#011dumping up to 1 collections in parallel)
CMDOUT (2020-11-03T19:01:02.334+0000#011writing local.oplog.rs to /home/ec2-user/cron/dump/2020-11-03T19:01:01Z/local/oplog.rs.bson.gz)
CMDOUT (2020-11-03T19:01:04.943+0000#011local.oplog.rs 0)
CMDOUT (2020-11-03T19:01:04.964+0000#011local.oplog.rs 0)
CMDOUT (2020-11-03T19:01:04.964+0000#011done dumping local.oplog.rs (0 documents))
CMDOUT (INFO: Dump success!)
CMDOUT (INFO: Replaying oplogs...)
CMDOUT (2020-11-03T19:01:05.030+0000#011using write concern: &{majority false 0})
CMDOUT (2020-11-03T19:01:05.054+0000#011will listen for SIGTERM, SIGINT, and SIGKILL)
CMDOUT (2020-11-03T19:01:05.055+0000#011connected to node type: standalone)
CMDOUT (2020-11-03T19:01:05.055+0000#011mongorestore target is a directory, not a file)
CMDOUT (2020-11-03T19:01:05.055+0000#011preparing collections to restore from)
CMDOUT (2020-11-03T19:01:05.055+0000#011found collection local.oplog.rs bson to restore to local.oplog.rs)
CMDOUT (2020-11-03T19:01:05.055+0000#011found collection metadata from local.oplog.rs to restore to local.oplog.rs)
CMDOUT (2020-11-03T19:01:05.055+0000#011restoring up to 4 collections in parallel)
CMDOUT (2020-11-03T19:01:05.055+0000#011replaying oplog)
CMDOUT (2020-11-03T19:01:05.055+0000#011applied 0 oplog entries)
CMDOUT (2020-11-03T19:01:05.055+0000#0110 document(s) restored successfully. 0 document(s) failed to restore.)
CMDOUT (INFO: Restore success!)
Sie können dieses Skript stoppen, nachdem Sie überprüft haben, dass keine oplogs
mehr vorhanden sind erstellt werden, d. h. wenn die Quell-DB offline ging.
Damit ist der vollständige Leitfaden zur Datenmigration von selbst gehosteter MongoDB abgeschlossen. Wenn Sie mehr über MongoDB erfahren möchten, finden Sie hier eine nützliche Ressource zur Verwendung von MongoDB als Datenquelle in goLang.