MongoDB Sharding: Praktische Schritt-für-Schritt-Anleitung

Verteilung von Daten mit Sharding in MongoDB

Sharding ist ein Verfahren, bei dem umfangreiche Datensätze in kleinere, besser handhabbare Teile aufgeteilt und über verschiedene MongoDB-Instanzen in einer verteilten Umgebung verteilt werden. Diese Technik ermöglicht es, die Speicherung und Verarbeitung von Daten effizienter zu gestalten.

Was genau ist Sharding?

MongoDB Sharding bietet eine skalierbare Methode zur Speicherung großer Datenmengen auf einer Reihe von Servern, anstatt alles auf einem einzigen Server zu konzentrieren. Diese Verteilung der Last ist entscheidend für die Leistungsfähigkeit des Systems.

In der Realität ist es unpraktisch, ständig wachsende Datenmengen auf einer einzigen Maschine zu speichern. Das Abfragen solcher großen Datenmengen auf einem einzelnen Server kann zu einer starken Auslastung der Ressourcen führen und möglicherweise nicht den gewünschten Durchsatz beim Lesen und Schreiben ermöglichen.

Grundsätzlich gibt es zwei Hauptansätze zur Skalierung, um mit den steigenden Datenmengen umzugehen:

Die vertikale Skalierung verbessert die Leistung eines einzelnen Servers durch Aufrüstung der Hardware, wie z.B. schnellere Prozessoren, mehr RAM oder zusätzlichen Speicherplatz. Diese Methode hat jedoch ihre Grenzen in der realen Anwendung aufgrund von Beschränkungen der verfügbaren Technologie und Hardwarekonfigurationen.

Die horizontale Skalierung hingegen fügt dem System weitere Server hinzu und verteilt die Last auf diese. Jede Maschine verarbeitet dabei einen Teil des Gesamtdatensatzes, was zu einer besseren Effizienz und einer kostengünstigeren Lösung führt als die Verwendung von High-End-Hardware. Allerdings erfordert dies auch eine komplexere Wartung der Infrastruktur mit einer größeren Anzahl von Servern.

MongoDB Sharding verwendet die horizontale Skalierungstechnik, um Daten effizient zu verteilen und zu verarbeiten.

Komponenten des Shardings

Um Sharding in MongoDB zu implementieren, sind folgende Schlüsselkomponenten erforderlich:

Ein Shard ist eine MongoDB-Instanz, die einen Teil des Gesamtdatensatzes verarbeitet. Shards werden in der Regel als Replikatsätze bereitgestellt, um eine hohe Verfügbarkeit zu gewährleisten.

Mongos fungiert als Schnittstelle zwischen der Client-Anwendung und dem Sharding-Cluster. Diese Instanz fungiert als Abfragerouter und leitet Anfragen an die entsprechenden Shards weiter.

Der Konfigurationsserver speichert Metadaten und Konfigurationsdetails des Clusters. MongoDB verlangt, dass dieser Server ebenfalls als Replikatsatz bereitgestellt wird, um die Datenintegrität zu gewährleisten.

Architektur des Shardings

Ein MongoDB-Cluster besteht aus einer Reihe von Replikatsätzen, die gemeinsam die Last verteilen.

Jeder Replikatsatz besteht aus mindestens drei oder mehr MongoDB-Instanzen. Ein Sharding-Cluster kann aus mehreren Shard-Instanzen bestehen, und jede dieser Instanzen arbeitet innerhalb eines eigenen Replikatsatzes. Anwendungen interagieren mit Mongos, welches wiederum mit den einzelnen Shards kommuniziert. Dadurch interagieren Anwendungen niemals direkt mit den Shard-Knoten, sondern immer über den Abfrage-Router, der die Daten basierend auf dem Shard-Schlüssel an die entsprechenden Shards verteilt.

Implementierung von Sharding

Die folgenden Schritte sind für die Implementierung des Shardings notwendig:

Schritt 1

  • Starten Sie den Konfigurationsserver als Replikatsatz und aktivieren Sie die Replikation zwischen den Servern.

mongod --configsvr --port 27019 --replSet rs0 --dbpath C:datadata1 --bind_ip localhost

mongod --configsvr --port 27018 --replSet rs0 --dbpath C:datadata2 --bind_ip localhost

mongod --configsvr --port 27017 --replSet rs0 --dbpath C:datadata3 --bind_ip localhost

Schritt 2

  • Initialisieren Sie den Replikatsatz auf einem der Konfigurationsserver.

rs.initiate( { _id : "rs0", configsvr: true, Mitglieder: [ { _id: 0, host: "IP:27017" }, { _id: 1, host: "IP:27018" }, { _id: 2, host: "IP:27019" } ] })

Schritt 3

  • Starten Sie die Sharding-Server als Replikatsätze und aktivieren Sie die Replikation zwischen ihnen.

mongod --shardsvr --port 27020 --replSet rs1 --dbpath C:datadata4 --bind_ip localhost

mongod --shardsvr --port 27021 --replSet rs1 --dbpath C:datadata5 --bind_ip localhost

mongod --shardsvr --port 27022 --replSet rs1 --dbpath C:datadata6 --bind_ip localhost

MongoDB initialisiert den ersten Sharding-Server als primär, um die Verwendung des primären Sharding-Servers zu verschieben, kann die movePrimary Methode benutzt werden.

Schritt 4

  • Initialisieren Sie den Replikatsatz auf einem der Sharding-Server.

rs.initiate( { _id : "rs0", Mitglieder: [ { _id: 0, host: "IP:27020" }, { _id: 1, host: "IP:27021" }, { _id: 2, host: "IP:27022" } ] })

Schritt 5

  • Starten Sie die Mongos-Instanz für den Sharded-Cluster.

mongos --port 40000 --configdb rs0/localhost:27019,localhost:27018, localhost:27017

Schritt 6

  • Verbinden Sie sich mit dem Mongo-Router-Server.

mongo --port 40000

  • Fügen Sie jetzt Sharding-Server hinzu.

sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")

Schritt 7

  • Aktivieren Sie in der Mongo-Shell das Sharding für Datenbanken und Sammlungen.
  • Aktivieren Sie das Sharding für die Datenbank.

sh.enableSharding("geekFlareDB")

Schritt 8

  • Für das Sharding ist der Shard-Schlüssel der Sammlung erforderlich (wird weiter unten in diesem Artikel erläutert).

Syntax: sh.shardCollection("dbName.collectionName", { "key" : 1 } )

sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } )

Hinweis: Wenn die Sammlung nicht existiert, erstellen Sie sie wie folgt.

db.createCollection("geekFlareCollection")

Schritt 9

Fügen Sie Daten in die Sammlung ein. Die MongoDB-Protokolle zeigen, dass ein Balancer aktiv ist und versucht, die Daten zwischen den Shards auszugleichen.

Schritt 10

Der letzte Schritt ist die Überprüfung des Sharding-Status. Dies erfolgt durch Ausführen des folgenden Befehls auf dem Mongos-Router-Knoten.

Sharding-Status

Überprüfen Sie den Sharding-Status, indem Sie den folgenden Befehl auf dem Mongo-Router-Knoten ausführen:

sh.status()

Datenverteilung

Der Mongos-Router verteilt die Last basierend auf dem Shard-Schlüssel auf die verschiedenen Shards. Um eine gleichmäßige Datenverteilung zu erreichen, wird ein Balancer eingesetzt.

Die Schlüsselkomponenten für die Datenverteilung auf Shards sind:

  • Ein Balancer ist für den Ausgleich der Daten zwischen den Shard-Knoten zuständig. Er wird aktiviert, wenn der Mongos-Server beginnt, die Last auf die Shards zu verteilen, und sorgt für eine gleichmäßigere Verteilung. Um den Status des Balancers zu überprüfen, verwenden Sie sh.status() oder sh.getBalancerState() oder sh.isBalancerRunning().

sh.isBalancerRunning()

ODER

sh.getBalancerState()

Nach dem Einfügen von Daten kann im Mongos-Daemon eine Aktivität beobachtet werden, die darauf hindeutet, dass der Balancer Chunks zwischen den Shards verschiebt, um die Daten auszugleichen. Dies kann zu Leistungsproblemen führen, daher wird empfohlen, den Balancer innerhalb eines bestimmten Zeitfensters auszuführen, wie im Balancer-Fenster beschrieben.

  • Der Shard-Schlüssel bestimmt die Logik für die Verteilung von Dokumenten aus einer Shard-Sammlung auf die Shards. Er kann ein indiziertes Feld oder ein indiziertes zusammengesetztes Feld sein, das in allen einzufügenden Dokumenten der Sammlung vorhanden sein muss. Die Daten werden in Chunks aufgeteilt, die jeweils einem Shard auf Basis des Shard-Schlüssels zugeordnet werden. Anhand dieses Schlüssels entscheidet der Router, welcher Shard einen bestimmten Chunk speichern soll.

Der Shard-Schlüssel sollte unter Berücksichtigung folgender Eigenschaften ausgewählt werden:

  • Kardinalität
  • Schreibleistung
  • Leseleistung
  • Lesekonsistenz
  • Leselokalität

Ein idealer Shard-Schlüssel stellt sicher, dass MongoDB die Last gleichmäßig auf alle Shards verteilt. Die Wahl eines geeigneten Schlüssels ist von entscheidender Bedeutung für die Leistung des Systems.

Entfernen eines Shard-Knotens

Vor dem Entfernen von Shards aus dem Cluster muss der Benutzer sicherstellen, dass die Daten sicher auf die verbleibenden Shards migriert werden. MongoDB stellt sicher, dass Daten sicher auf andere Shard-Knoten übertragen werden, bevor der gewünschte Shard-Knoten entfernt wird.

Um einen Shard-Knoten zu entfernen, befolgen Sie diese Schritte:

Schritt 1

Zuerst muss der Hostname des zu entfernenden Shards ermittelt werden. Der folgende Befehl listet alle im Cluster vorhandenen Shards zusammen mit ihrem Status auf.

db.adminCommand( { listShards: 1 } )

Schritt 2

Geben Sie den folgenden Befehl aus, um den erforderlichen Shard aus dem Cluster zu entfernen. Nach der Ausführung kümmert sich der Balancer um das Entfernen von Chunks aus dem zu entfernenden Shard-Knoten und gleicht dann die Verteilung der verbleibenden Chunks auf die restlichen Shard-Knoten aus.

db.adminCommand( { removeShard: "shardedReplicaNodes" } )

Schritt 3

Um den Status des zu entfernenden Shards zu prüfen, geben Sie den gleichen Befehl erneut ein. Wir müssen warten, bis der Abbau der Daten abgeschlossen ist. Die Felder „msg“ und „state“ zeigen an, ob der Abbau der Daten abgeschlossen ist oder nicht.

"msg" : "draining ongoing", "state" : "ongoing"

Wir können den Status auch mit dem Befehl sh.status() überprüfen. Wenn der Abbau noch andauert, wird der Shard-Knoten mit dem Status „draining: true“ angezeigt.

Schritt 4

Überprüfen Sie weiterhin den Status des Datenabbaus mit demselben Befehl, bis der benötigte Shard vollständig entfernt ist.
Sobald der Vorgang abgeschlossen ist, geben die Befehlsausgabe die Nachricht und den Status als abgeschlossen wieder.

"msg" : "removeshard completed successfully", "state" : "completed", "shard" : "rs1", "ok" : 1,

Schritt 5

Zuletzt sollten wir die verbleibenden Shards im Cluster überprüfen. Verwenden Sie hierfür den Befehl sh.status() oder db.adminCommand( { listShards: 1 } ).

Es ist nun ersichtlich, dass der entfernte Shard nicht mehr in der Liste der Shards enthalten ist.

Vorteile von Sharding gegenüber Replikation

  • Bei der Replikation werden alle Schreibvorgänge vom primären Knoten bearbeitet, während sekundäre Server Sicherungskopien verwalten oder schreibgeschützte Operationen ausführen. Beim Sharding in Verbindung mit Replikatsätzen wird die Last auf mehrere Server verteilt.
  • Ein einzelner Replikatsatz ist auf 12 Knoten begrenzt, aber es gibt keine Einschränkung hinsichtlich der Anzahl der Shards.
  • Die Replikation erfordert High-End-Hardware oder vertikale Skalierung, um große Datensätze zu verarbeiten, was im Vergleich zum Hinzufügen zusätzlicher Server beim Sharding teurer ist.
  • Bei der Replikation kann die Leseleistung durch das Hinzufügen weiterer Slave-/Sekundärserver verbessert werden, während beim Sharding sowohl die Lese- als auch die Schreibleistung durch das Hinzufügen weiterer Shard-Knoten verbessert werden.

Einschränkungen von Sharding

  • Der Shard-Cluster unterstützt keine eindeutige Indizierung über die Shards hinweg, es sei denn, der vollständige Shard-Schlüssel ist dem eindeutigen Index vorangestellt.
  • Alle Aktualisierungsoperationen für die Shard-Sammlung müssen den Shard-Schlüssel oder das Feld _id in der Abfrage enthalten.
  • Sammlungen können nur dann fragmentiert werden, wenn ihre Größe einen bestimmten Schwellenwert überschreitet. Dieser Wert wird auf der Grundlage der durchschnittlichen Größe der Shard-Schlüssel und der konfigurierten Chunk-Größe geschätzt.
  • Sharding hat Einschränkungen in Bezug auf die maximale Größe einer Sammlung oder die Anzahl der Splittings.
  • Die Wahl des falschen Shard-Schlüssels kann zu Leistungsproblemen führen.

Zusammenfassung

MongoDB bietet integriertes Sharding zur Implementierung großer Datenbanken ohne Leistungseinbußen. Ich hoffe, die obigen Informationen helfen Ihnen bei der Einrichtung von MongoDB-Sharding. Als Nächstes sollten Sie sich mit einigen der häufig verwendeten MongoDB-Befehle vertraut machen.