Ein massives Datenwachstum ist mit Kosten für reduzierten Durchsatz verbunden, insbesondere wenn die Daten von einem einzelnen Server bedient werden. Sie können diese Leistung jedoch verbessern, indem Sie die Anzahl der Server erhöhen und Ihre Daten auch auf mehrere dieser Server verteilen. In diesem Artikel, Replikatsätze in MongoDB, haben wir ausführlich besprochen, wie die Durchsatzvorgänge verbessert werden können, abgesehen von der Sicherstellung einer hohen Datenverfügbarkeit. Dieser Prozess kann nicht vollständig erreicht werden, ohne Sharding in MongoDB zu erwähnen.
Was ist Sharding in MongoDB
MongoDB ist so flexibel konzipiert, dass es für Sie skalierbar ist, um in einem Cluster auf einer verteilten Plattform ausgeführt zu werden. Auf dieser Plattform werden Daten zur Speicherung auf mehrere Server verteilt. Dieser Vorgang wird als Sharding bezeichnet. Wenn ein einzelner Server einer großen Datenmenge zur Speicherung ausgesetzt ist, geht Ihnen möglicherweise der Speicherplatz aus. Außerdem können sehr kritische Durchsatzoperationen wie Lesen und Schreiben stark beeinträchtigt werden. Die horizontale Skalierungsfunktion in MongoDB ermöglicht es uns, Daten auf mehrere Computer zu verteilen, was letztendlich zu einer verbesserten Lastverteilung führt.
MongoDB-Shards
Ein Shard kann als ein Replikatsatz betrachtet werden, der eine Datenteilmenge hostet, die in einem Sharding-Cluster verwendet wird. Für eine bestimmte Mongod-Instanz mit einem Datensatz werden die Daten aufgeteilt und über eine Reihe von Datenbanken verteilt, in diesem Fall Shards. Grundsätzlich dienen eine Reihe verschiedener Shards als unabhängige Datenbanken, aber zusammen bilden sie eine logische Datenbank. Shards reduzieren die Arbeitslast, die von der gesamten Datenbank ausgeführt werden muss, indem sie die Anzahl der Operationen reduzieren, die ein Shard verarbeiten sollte, abgesehen von der geringeren Datenmenge, die dieser Shard hosten wird. Diese Metrik bietet Raum für die horizontale Erweiterung eines Clusters. Eine einfache Sharding-Architektur ist unten dargestellt.
Daten, die von einer Clientanwendung gesendet werden, werden von Servertreibern abgefangen und dann an den Router weitergeleitet. Der Router konsultiert dann die Serverkonfigurationen, um zu bestimmen, wo der Lese- oder Schreibvorgang auf den Shard-Servern angewendet werden soll. Kurz gesagt, für eine Operation wie das Schreiben hat es einen Index, der vorschreibt, welcher Shard der Datensatz ist, der der Host sein soll. Nehmen wir an, eine Datenbank hat eine Datenkapazität von 1 TB, die auf 4 Shards verteilt ist. Jeder Shard enthält 256 GB dieser Daten. Mit einer reduzierten Datenmenge, die ein Shard verarbeiten kann, können Operationen recht schnell durchgeführt werden. Sie sollten in Erwägung ziehen, den Sharding-Cluster in Ihrer Datenbank zu verwenden, wenn:
- Sie erwarten, dass die Datenmenge in Zukunft Ihre Einzelinstanz-Speicherkapazität übersteigen wird.
- Wenn die Schreibvorgänge von der einzelnen MongodB-Instanz nicht ausgeführt werden können
- Der RAM des Arbeitsspeichers mit wahlfreiem Zugriff geht auf Kosten einer erhöhten Größe des aktiven Arbeitssatzes aus.
Sharding bringt neben zusätzlichen Ressourcen auch eine erhöhte Komplexität in der Architektur mit sich. Es ist jedoch ratsam, Sharding in einem frühen Stadium durchzuführen, bevor Ihre Datenmenge zu groß wird, da dies ziemlich mühsam ist, wenn Ihre Datenkapazität überschritten wird.
MongoDB-Shard-Schlüssel
Wie wir alle wissen, hat ein Dokument in MongoDB Felder zum Halten von Werten. Wenn Sie ein Sharding bereitstellen, müssen Sie ein Feld aus einer Sammlung auswählen, das Sie zum Aufteilen der Daten verwenden. Dieses von Ihnen ausgewählte Feld ist der Shard-Schlüssel, der bestimmt, wie Sie die Dokumente in der Sammlung auf mehrere Shards aufteilen. In einem einfachen Beispiel können Ihre Daten die Feldnamen Schüler, Klassenlehrer und Noten enthalten. Sie können festlegen, dass ein Shard-Satz die Dokumente mit dem Index-Schüler enthält, ein anderer Lehrer und Noten. Sie können jedoch verlangen, dass Ihre Daten zufällig verteilt werden, verwenden Sie daher einen gehashten Shard-Schlüssel. Neben dem gehashten Shard-Schlüssel gibt es eine Reihe von Shard-Schlüsseln, die zum Aufteilen von Daten verwendet werden, aber die beiden Hauptkategorien sind indizierte Felder und indizierte zusammengesetzte Felder.
Auswahl eines Shard-Schlüssels
Für eine bessere Funktionalität, Leistungsfähigkeit und Leistung der Sharding-Strategie müssen Sie den geeigneten Sharding-Schlüssel auswählen. Die Auswahlkriterien sind von 2 Faktoren abhängig:
- Schemastruktur Ihrer Daten. Wir können zum Beispiel ein Feld betrachten, dessen Wert steigend oder fallend (sich monoton ändernd) sein könnte. Dies wirkt sich höchstwahrscheinlich auf eine Verteilung von Inserts auf einen einzelnen Shard innerhalb eines Clusters aus.
- Wie Ihre Abfragekonfigurationen zum Ausführen von Schreibvorgängen ausgestattet sind.
Was ist ein gehashter Shard-Schlüssel
Dabei wird ein Hash-Index eines einzelnen Felds als Shard-Schlüssel verwendet. Ein Hash-Index ist ein Index, der Einträge mit Hashes der Werte eines indizierten Felds verwaltet, z. B.
{
"_id" :"5b85117af532da651cc912cd"
}
Um einen Hash-Index zu erstellen, können Sie diesen Befehl in der Mongo-Shell verwenden.
db.collection.createIndex( { _id: hashedValue } )
Wobei die HashedValue-Variable eine Zeichenfolge Ihres angegebenen Hash-Werts darstellt. Hash-Sharding fördert die gleichmäßige Datenverteilung über einen Sharding-Cluster und reduziert dadurch Zieloperationen. Es ist jedoch unwahrscheinlich, dass sich Dokumente mit fast denselben Shard-Schlüsseln auf demselben Shard befinden, sodass eine Mongo-Instanz einen Broadcast-Vorgang ausführen muss, um ein bestimmtes Abfragekriterium zu erfüllen.
Bereichsbasierter Shard-Schlüssel
In dieser Kategorie wird der Datensatz basierend auf Wertebereichen eines ausgewählten Feldschlüssels partitioniert, daher eine große Bandbreite an Partitionen. D.h. Wenn Sie einen numerischen Schlüssel haben, dessen Werte von negativ unendlich bis positiv unendlich laufen, fällt jeder Shard-Schlüssel auf einen bestimmten Punkt innerhalb dieser Zeile. Diese Zeile ist in Chunks unterteilt, wobei jeder Chunk einen bestimmten Wertebereich hat. Genau diese Dokumente mit fast ähnlichen Shard-Schlüsseln werden im selben Chunk gehostet. Der Vorteil dieser Technik besteht darin, dass sie eine Reihe von Abfragen unterstützt, da der Router den Shard mit dem spezifischen Chunk auswählt.
Merkmale eines optimalen Shard-Schlüssels
- Ein idealer Shard-Schlüssel sollte in der Lage sein, auf einen einzelnen Shard abzuzielen, um ein Mongos-Programm so zu verbessern, dass Abfragevorgänge von einer einzelnen Mongod-Instanz zurückgegeben werden. Das Schlüsselwort Primärfeld kennzeichnet dies. D.h. nicht in einem eingebetteten Dokument.
- Haben einen hohen Grad an Zufälligkeit. Das heißt, das Feld sollte in den meisten Dokumenten verfügbar sein. Dadurch wird sichergestellt, dass Schreibvorgänge innerhalb eines Shards verteilt werden.
- Sei leicht teilbar. Mit einem leicht teilbaren Shard-Schlüssel gibt es eine erhöhte Datenverteilung und somit mehr Shards.
Komponenten einer Produktionscluster-Bereitstellung
In Bezug auf die oben gezeigte Architektur sollte der Produktions-Shard-Cluster Folgendes haben:
- Mongos/Router abfragen. Dies sind Mongo-Instanzen, die als Server zwischen Anwendungstreibern und der Datenbank selbst fungieren. Bei der Bereitstellung wird der Load Balancer so konfiguriert, dass er die Verbindung von einem einzelnen Client zum Erreichen derselben Mongos ermöglicht.
- Scherben. Dies sind die Partitionen, in denen Dokumente mit derselben Shard-Key-Definition gehostet werden. Sie sollten mindestens 2 haben, um die Datenverfügbarkeit zu erhöhen.
- Konfigurationsserver:Sie können entweder 3 separate Konfigurationsserver auf verschiedenen Computern haben oder eine Gruppe davon, wenn Sie mehrere Sharding-Cluster haben.
Bereitstellung eines Sharded-Clusters
Die folgenden Schritte geben Ihnen eine klare Richtung zur Bereitstellung Ihres Sharding-Clusters.
-
Host für die Konfigurationsserver erstellen. Standardmäßig sind die Serverdateien im Verzeichnis /data/configdb verfügbar, aber Sie können dies jederzeit auf Ihr bevorzugtes Verzeichnis festlegen. Der Befehl zum Erstellen des Datenverzeichnisses lautet:
$ mkdir /data/configdb
-
Starten Sie die Konfigurationsserver, indem Sie den Port und den Dateipfad für jeden mit dem Befehl
definieren$ mongod --configsvr --dbpath /data/config --port 27018
Dieser Befehl startet die Konfigurationsdatei im Datenverzeichnis mit dem Namen config auf Port 27018. Standardmäßig laufen alle MongoDB-Server auf Port 27017.
-
Starten Sie eine Mongos-Instanz mit der folgenden Syntax:
$ mongo --host hostAddress --port 27018.
Die hostAddress-Variable hat den Wert für den Hostnamen oder die IP-Adresse Ihres Hosts.
-
Starten Sie Mongod auf dem Shard-Server und initiieren Sie es mit dem Befehl:
mongod --shardsvr --replSet rs.initiate()
-
Starten Sie Ihren Mongos auf dem Router mit dem Befehl:
mongos --configdb rs/mongoconfig:27018
-
Hinzufügen von Shards zu Ihrem Cluster. Nehmen wir an, wir haben den Standardport 27017 als unseren Cluster, wir können einen Shard auf Port 27018 wie folgt hinzufügen:
mongo --host mongomaster --port 27017 sh.addShard( "rs/mongoshard:27018") { "shardAdded" : "rs", "ok" : 1 }
-
Aktivieren Sie das Sharding für die Datenbank mithilfe des Shard-Namens mit dem folgenden Befehl:
sh.enableSharding(shardname) { "ok" : 1 }
Sie können den Status des Shards mit dem folgenden Befehl überprüfen:
sh.status()
Diese Informationen werden Ihnen angezeigt
sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("59f425f12fdbabb0daflfa82") } shards: { "_id" : "rs", "host" : "rs/mongoshard:27018", "state" : 1 } active mongoses: "3.4.10" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no NaN Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : shardname, "primary" : "rs", "partitioned" : true }
Shard-Balancing
Nach dem Hinzufügen eines Shards zu einem Cluster stellen Sie möglicherweise fest, dass einige Shards möglicherweise immer noch mehr Daten hosten als andere, und dass der neue Shard aus Gründen der Übersichtlichkeit keine Daten enthält. Sie müssen daher einige Hintergrundprüfungen durchführen, um den Lastausgleich sicherzustellen. Das Balancing ist die Grundlage für die Umverteilung von Daten in einem Cluster. Der Balancer erkennt eine ungleichmäßige Verteilung und migriert daher Chunks von einem Shard zum anderen, bis ein Gleichgewichtsquorum erreicht ist.
Der Ausgleichsprozess verbraucht neben den Arbeitsbelastungs-Overheads viel Bandbreite, was sich auf den Betrieb Ihrer Datenbank auswirkt. Ein besserer Ausgleichsprozess beinhaltet:
- Einen einzelnen Block auf einmal verschieben.
- Führen Sie den Ausgleich durch, wenn der Migrationsschwellenwert erreicht ist, d. h. wenn die Differenz zwischen der niedrigsten Anzahl von Blöcken für eine bestimmte Sammlung und der höchsten Anzahl von Blöcken in der fragmentierten Sammlung vorliegt.