MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Ein Entwicklerleitfaden für MongoDB-Replikatsätze

MongoDB erfordert oft die Arbeit mit einer großen Menge von Daten, einschließlich eingebetteter Arrays und Array-Objekte. Daher ist es immer wichtig sicherzustellen, dass Ihre Datenbankverarbeitungsrate so schnell wie möglich ist, um Lese- und Schreibvorgänge zu verbessern. Um Datenanomalien zu vermeiden, die aufgrund von Dateninkonsistenz auftreten können, müssen Sie außerdem sicherstellen, dass Ihre Daten in erhöhter Verfügbarkeit sind, nur für den Fall, dass Sie nach einem Hardwarefehler oder einigen Dienstunterbrechungen eine Wiederherstellung wünschen. MongoDB stellt zu diesem Zweck zwei Konzepte bereit – ReplicaSets und Sharding.

Replikation in MongoDB

Master-Slave-Replikation

Dies ist eine der ältesten Techniken, die verwendet wird, um sicherzustellen, dass die Daten den Benutzern immer zur Verfügung stehen, selbst wenn ein System ausfällt. Die Master-Slave-Replikation ist jedoch in den neuesten Versionen von MongoDB ab 3.2 veraltet und wurde daher durch Replikatsätze ersetzt.

Um diese Konfiguration vorzunehmen, startet man 2 Mongod-Instanzen, wobei man davon ausgeht, dass sich eine im Master-Modus und die andere im Slave-Modus befindet.

Um eine Instanz im Master-Modus zu starten, führen Sie Folgendes aus:

mongod --master --port portNumber

Die Option --master weist mongod an, eine local.oplog.$main-Sammlung zu erstellen, mit der eine Liste von Operationen in die Warteschlange gestellt wird, damit die Slaves sie beim Replizieren der Daten anwenden können.

Um eine Mongod-Instanz im Slave-Modus zu starten, führen Sie einfach Folgendes aus:

mongod --slave --source <masterhostname><:<port>>

Hier müssen Sie den Hostnamen und den Port der Masterinstanz für das Argument --source angeben. Dies ist eine zusammenfassende Übersicht über die Verwendung der Master-Slave-Replikation, und da sie veraltet ist, gilt unser Interesse den Replica-Sets.

Replik-Sets

Dies ist eine Gruppe von MongoDB-Prozessen, die als Mongod-Instanzen bekannt sind und im Grunde denselben Datensatz hosten. Es besteht aus einem primären Knoten und mehreren sekundären Knoten für Lagerdaten. Der primäre Knoten empfängt alle Schreiboperationen und zeichnet alle anderen Änderungen an seinem Datensatz in seinem Operationsprotokoll auf. Die sekundären Knoten replizieren am anderen Ende das Operationsprotokoll des primären Knotens und wenden die Operationen auf ihren Datensatz an, sodass ihre Datensätze den Datensatz des primären Knotens widerspiegeln. In einfachen Worten können wir sagen, dass wir Maschine A als primären Knoten und Maschine B und C als sekundäre Knoten haben. Maschine A empfängt eine Schreiboperation und nimmt Änderungen an ihren Daten vor und erstellt dann eine Liste der vorgenommenen Änderungen. Die Maschinen B und C kopieren dann Operationen aus der bereitgestellten Liste, in diesem Fall das Oplog, und führen sie aus, sodass die resultierenden Daten dieselben sind wie in Maschine A.

Wie bereits erwähnt, ist es immer wichtig, eine hohe Datenverfügbarkeit zu gewährleisten, insbesondere im Produktionsumfeld. Die Replikation hilft, indem sie Datenredundanz in verschiedenen Mongod-Instanzen bereitstellt. Da Kopien derselben Daten in verschiedenen Datenbanken an mehreren Orten gespeichert sind, ist es im Falle eines Datenverlusts einfach, sie in der vorhandenen wiederherzustellen.

Bei vielen laufenden Instanzen werden Lese- und Schreibvorgänge von Clients an unterschiedliche Server gesendet und damit die Verarbeitungsrate erhöht. Die Grundstruktur des Replikationsprozesses ist unten dargestellt.

Manchmal ist der primäre Server möglicherweise nicht verfügbar, beispielsweise aufgrund einer Unterbrechung der Internetverbindung oder einer Dienstunterbrechung. In diesem Fall ernennt der Replikatsatz einen sekundären Knoten als primären Knoten. So sehr die Leseanforderungen grundsätzlich an die primäre gesendet werden, können die Leseanforderungen in einigen Fällen an die sekundären gesendet werden, aber seien Sie vorsichtig, da die zurückgegebenen Daten möglicherweise nicht den Inhalt der primären wiedergeben oder die Daten möglicherweise nicht auf dem neuesten Stand sind.

Schiedsrichter

Im Falle der Wahl eines Primären benötigen Sie eine zusätzliche Mongod-Instanz zum Replikatsatz, um eine Stimme im Wahlprozess hinzuzufügen. Diese Instanz wird als Arbiter bezeichnet und ihre herausragenden Merkmale sind:

  1. Es hat keine Kopie des Datensatzes und erfordert daher nicht so leistungsstarke Hardware wie die datentragenden Knoten.
  2. Kann nicht zum Primären befördert werden.
  3. Sie haben immer 1 Wahlstimme, damit das Replikat-Set eine ungerade Anzahl von stimmberechtigten Mitgliedern haben kann, ohne dass ein zusätzliches Mitglied die Daten repliziert. Seine entscheidende Rolle besteht daher darin, einen primären Knoten auszuwählen, wenn er nicht verfügbar ist.
  4. Er bleibt unverändert.

Im Gegensatz zum Arbiter können andere Replikat-Sets in primäre von sekundären und umgekehrt konvertiert werden.

Asynchrone Replikation

Der Replikationsprozess findet in zwei Formen der Datensynchronisation statt. Zunächst werden die Mitglieder im Satz bei der anfänglichen Synchronisierung mit vollständigen Daten gefüllt. Die anschließende Replikation erfolgt, um fortschreitende Änderungen auf den gesamten Datensatz anzuwenden.

Bei der anfänglichen Synchronisierung werden Daten von einem Mitglied des Replikatsatzes in ein anderes kopiert. Wenn der Prozess abgeschlossen ist, geht das Mitglied in den sekundären Knoten über.

Automatisches MongoDB-Failover

Es kann zu einer Dienstunterbrechung wie einer Netzwerktrennung kommen, die mit der Beendigung der Kommunikation zwischen dem primären und dem sekundären Netzwerk einhergeht. Wenn die Trennung länger als 10 Sekunden dauert oder vollständig fehlschlägt, stimmt der verbleibende Replikatsatz für ein Mitglied, das der neue primäre wird. Der sekundäre Knoten, der die Mehrheit der Stimmen erhält, wird zum neuen primären Knoten.

In Version 3.0 von MongoDB kann ein Replikatsatz bis zu 50 Mitglieder mit 7 stimmberechtigten Mitgliedern haben.

Priorität Zero Replica Set-Mitglieder

Dies sind sekundäre Mitglieder, die weder zu primären Knoten werden können, noch eine Wahl auslösen können. Die entscheidenden Rollen im Datensatz sind:Beibehaltung von Datensatzkopien, Auswahl eines primären Knotens und Durchführung von Lesevorgängen. Sie fungieren wie ein Backup, bei dem ein neues Mitglied möglicherweise nicht sofort hinzugefügt wird. Es speichert somit die aktualisierten Daten und kann ein nicht verfügbares Mitglied sofort ersetzen.

MongoDB Hidden Replica Set-Mitglieder

Dies sind Mitglieder ohne Verbindung zu den Clientanwendungen. Sie werden für Workloads mit unterschiedlichen Nutzungsanforderungen von anderen sekundären Mitgliedern verwendet. Sie erhalten nur den grundlegenden Replikationsdatenverkehr während der anfänglichen Synchronisierung.

MongoDB Delayed Replica Set-Mitglieder

Diese kopieren Daten aus der Oplog-Datei des primären Knotens innerhalb einer bestimmten Dauer. Sie spiegeln immer den verzögerten Zustand oder eine frühere Form der Menge wider. Sie sind daher wichtig für die Erkennung von Fehlern und geben einen Hinweis darauf, wie man diese Fehler beheben kann, beispielsweise wenn eine Datenbank gelöscht wurde. Bei der Auswahl des Verzögerungsbetrags sollte Folgendes berücksichtigt werden:

  1. Die Dauer sollte geringer sein als die Kapazität des Betriebsprotokolls, die für die WiredTiger-, MMAPv1- und In-Memory-Speicher-Engines 50 GB beträgt. Andernfalls kann das verzögerte Mitglied Vorgänge nicht erfolgreich replizieren.
  2. Die Dauer der Verzögerung sollte gleich oder etwas länger sein als die Dauer Ihres erwarteten Wartungsfensters.

Konfiguration

Dies ist ein Prioritäts-Null-Mitglied, es ist verborgen, daher für Bewerbungen nicht sichtbar, und kann schließlich am Wahlverfahren teilnehmen. Nehmen wir also an, Sie haben 10 Mitglieder in Ihrem Replikatsatz, um eine Priorität zu konfigurieren, können Sie ein Mitglied an Position n als Mitglied[n] auswählen und seine Eigenschaften wie folgt festlegen:

{
    “_id”: <num>, 
    “Host”: <hostname: port>,
    “Priority”: 0,
    “slaveDelay”: <seconds>,
    “Hidden”: true
} 

Oder verwenden Sie die Mongo-Shell, die mit der primären verbunden ist, und führen Sie diese Befehle aus, um das erste Mitglied des Replikatsatzes als verzögert festzulegen:

cfg = rs.conf()
cfg.members[0].priority = 0
cfg.members[0].hidden = true
cfg.members[0].slaveDelay = 3600
rs.reconfig(cfg)

Nach dem Festlegen dieser Konfigurationen kann die verzögerte sekundäre nicht zu einer primären werden und daher vor Anwendungen verborgen werden. Das Mitglied wird um 1 Stunde (3600 Sekunden) von den Oplog-Operationen verzögert.

Multiplenines Become a MongoDB DBA – Bringing MongoDB to ProductionErfahren Sie, was Sie wissen müssen, um MongoDBDownload for Free bereitzustellen, zu überwachen, zu verwalten und zu skalieren

So starten Sie ein Replikat-Set

In dieser Anleitung werden wir Schritt für Schritt sehen, wie wir einen Replikatsatz in MongoDB konfigurieren können.

  1. Nehmen wir an, Sie haben 3 Mongodb, die Sie replizieren möchten, und sie sind wie folgt konfiguriert:
    1. Mongod1.conf läuft auf Port 27017
    2. Mongod2.conf läuft auf Port 27018
    3. Mongod3.conf läuft auf Port 27019

    Stellen Sie sicher, dass Sie den Replikatsatznamen hinzufügen, der sich in jeder Datei nicht ändert. Sie können dies tun, indem Sie die Option replSet value zu einem Namen Ihrer Wahl hinzufügen oder ändern.

  2. Wir können die erste Instanz starten, indem wir

    ausführen
    sudo mongod --config /etc/mongo/mongod1.conf

    Dies ist der Fall, wenn Sie keine Mongod-Instanz haben. Dann machen Sie dasselbe für die anderen Instanzen. Um nach laufenden Instanzen auf Ihrem Computer zu suchen, führen Sie

    aus
    ps -ax | grep mongo

    Sie erhalten eine Liste wie diese:

    4328 ttys000    0:06.15 mongod
    4950 ttys001    0:00.00 grep mongo
    Das bedeutet, dass die erste Instanz in MongoDB standardmäßig auf Port 27017 läuft, daher haben wir sie als erste in der Liste. Wenn Sie die anderen gestartet haben, werden sie auch in der Liste mit ihren entsprechenden Pfad-URLs aufgeführt. Um eine Verbindung zu einer Instanz in der Mongo-Shell herzustellen, führen Sie diesen Befehl aus:
    mongo  --port port_number i.e mongo  --port 27017.
    In unserem Fall müssen wir uns jedoch mit einem Replikat-Set-Namen verbinden, also müssen wir den Namen zum Befehl hinzufügen:
    mongod --replSet replicaSetName --dbpath /usr/local/var/mongo/mongod --port 27017
    In diesem Fall ist unser replicaSetName =„testrep“
  3. Prüfen wir, ob ein Replikatsatz aktiviert ist, indem wir rs.status()

    ausführen

    Wenn Sie ein Ergebnis erhalten wie:

    {
        "ok" : 0,
        "errmsg" : "not running with --replSet",
        "code" : 76,
        "codeName" : "NoReplicationEnabled"
    }

    Dann bedeutet dies, dass kein Replikatsatz aktiviert ist. Andernfalls erhalten Sie das Ergebnis als

    {
        "operationTime" : Timestamp(0, 0),
        "ok" : 0,
        "errmsg" : "no replset config has been received",
        "code" : 94,
        "codeName" : "NotYetInitialized",
        "$clusterTime" : {
            "clusterTime" : Timestamp(0, 0),
            "signature" : {
                "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                "keyId" : NumberLong(0)
            }
        }
    }

    dann bedeutet dies, dass die Replikation noch nicht initiiert wurde.

  4. Die Methode rs.initiate() hilft uns, einen neuen Replikatsatz zu starten, und die Instanz, in der er initiiert wird, wird zu unserem primären Knoten. Wir können also in unserer Instanz eine initiieren, indem wir die Methode „initiate“ ausführen. rs.initiate().

  5. Überprüfen Sie den Status des Replikatsatzes erneut, indem Sie rs.status().members ausführen. Sie sollten jetzt so etwas wie

    sehen
    "members" : [
            {
                "_id" : 0,
                "name" : "localhost:27018",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 577,
                "optime" : {
                    "ts" : Timestamp(1535301271, 1),
                    "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2018-08-26T16:34:31Z"),
                "syncingTo" : "",
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "could not find member to sync from",
                "electionTime" : Timestamp(1535301265, 1),
                "electionDate" : ISODate("2018-08-26T16:34:25Z"),
                "configVersion" : 1,
                "self" : true,
                "lastHeartbeatMessage" : ""
            }
        ]

    Gut zu gehen. Unser Interesse wird die Mitgliederoption sein, da wir sehen können, dass es sich um ein n-Array mit 1 Mitglied handelt. Wenn Sie die Option stateStr des ersten Mitglieds aktivieren, ist sie in diesem Fall auf Primary gesetzt, was bedeutet, dass dies als unser primärer Knoten fungiert.

  6. Fügen Sie dem Replikatsatz ein neues Mitglied unter Verwendung seines Hostnamens hinzu. Um nach dem Hostnamen der verbundenen Instanz zu suchen, die Sie hinzufügen möchten, führen Sie

    aus
    db.serverStatus().host

    Sie erhalten so etwas wie

    ervername.local:27019

    Von PRIMARY aus können Sie also ein weiteres Mitglied hinzufügen, indem Sie diesen Befehl in der Mongo-Shell ausführen:

    rs.add("servername.local:27019");
  7. Führen Sie den Statusbefehl

    aus
    rs.status().members

    Um zu überprüfen, ob die Änderungen vorgenommen wurden.

    Sie sollten jetzt so etwas haben:

    [
        {
            "_id" : 0,
            "name" : "localhost:27018",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 11479,
            "optime" : {
                "ts" : Timestamp(1535312183, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2018-08-26T19:36:23Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "",
            "electionTime" : Timestamp(1535301265, 1),
            "electionDate" : ISODate("2018-08-26T16:34:25Z"),
            "configVersion" : 2,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 1,
            "name" : "127.0.0.1:27019",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 15,
            "optime" : {
                "ts" : Timestamp(1535312183, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1535312183, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2018-08-26T19:36:23Z"),
            "optimeDurableDate" : ISODate("2018-08-26T19:36:23Z"),
            "lastHeartbeat" : ISODate("2018-08-26T19:36:26.302Z"),
            "lastHeartbeatRecv" : ISODate("2018-08-26T19:36:27.936Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "localhost:27018",
            "syncSourceHost" : "localhost:27018",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 2
        }
    ]

    Wir haben jetzt 2 Mitglieder, eines ist ein PRIMARY-Knoten und das andere ein SECONDARY-Knoten. Sie können weitere Mitglieder hinzufügen, jedoch nicht mehr als 50. Lassen Sie uns nun eine Datenbank in der Instanz an Port 27018 als primäre erstellen.

    Wenn wir die primäre trennen, findet ein Failover statt, und da wir nur eine primäre haben, wird sie automatisch in eine sekundäre überführt. Wenn wir uns jetzt mit der auf Port 27019 verbinden, sollten Sie dieselben Datenbanken und Sammlungen mit ihren Dokumenten erhalten.

    Wenn nun der getrennte Primärknoten wieder verbunden wird, wird er als Sekundärknoten hinzugefügt, da er Operationen aus dem Oplog des vorhandenen Primärknotens kopiert.

MongoDB Replica Set Write Concern

Wenn MongoDB ein erfolgreiches Journaling-Schreiben zurückgibt, werden die Daten auf der Festplatte gespeichert und stehen somit nach dem Neustart von Mongod zur Verfügung. Bei den Schreibvorgängen sind die Daten jedoch nur dauerhaft, nachdem sie repliziert und von der Mehrheit der stimmberechtigten Mitglieder des Replikatssatzes an das Journal übergeben wurden.

Einige Daten sind möglicherweise zu groß zum Aktualisieren oder Einfügen, daher kann es länger als erwartet dauern, bis die Daten in anderen Mitgliedern repliziert werden. Aus diesem Grund ist es ratsam, die Konfigurationen von writeConcern entsprechend der Dauer anzupassen, innerhalb derer eine Operation ausgeführt werden soll. Die Standardkonfigurationen von writeConcern schreiben vor, dass der Replikatsatz nur vom primären Mitglied bestätigt werden muss. Ein standardmäßiger Schreibbereich bestätigt Schreibvorgänge nur für den Primärspeicher, kann jedoch außer Kraft gesetzt werden, um Schreibvorgänge auf einigen Replikatsatzmitgliedern zu überprüfen, indem der Schreibbereich für einen bestimmten Schreibvorgang angegeben wird. Zum Beispiel:

db.books.insert({name: “James”,place: “Beijing”},{writeConcern: {w: 3, wtimeout: 3600}})

Die Schreiboption diktiert in diesem Fall, dass die Operation erst dann eine Antwort zurückgeben soll, nachdem sie auf die primäre und mindestens 2 sekundäre Datenbanken verteilt wurde oder nach 3,6 Sekunden eine Zeitüberschreitung eintritt.

Konfigurieren des Write Concern für MongoDB

Die MongoDB-Option „getLastErrorDefaults“ gibt uns die Parameter zum Ändern der Standardeinstellungen für Schreibangelegenheiten in der Replikatsatzkonfiguration. Dies bedeutet, dass die Operation in den meisten stimmberechtigten Mitgliedern abgeschlossen sein muss, bevor das Ergebnis zurückgegeben wird.

cfg = rs.conf()
cfg.settings = {},
cfg.settings.getLastErrorDefaults = {w: “majority”, wtimeout: 3600}
rs.reconfig(cfg)

Der Zeitüberschreitungswert verhindert das Blockieren von Schreibvorgängen, d. h. wenn 5 Mitglieder vorhanden sein sollen, um das Schreibproblem zu bestätigen, aber leider 4 oder weniger Mitglieder im Replikatsatz vorhanden sind, wird der Vorgang blockiert, bis alle Mitglieder verfügbar sind. Durch Hinzufügen der Timeout-Schwelle wird die Operationsblockierung nach dieser Dauer verworfen.

Replikationsblockierung

Das Blockieren einer Operation, insbesondere wenn alle Mitglieder repliziert wurden, stellt sicher, dass keine Zeit mehr verschwendet wird, um darauf zu warten, dass ein anderes Replikatsatzmitglied verfügbar ist, um eine Antwort zurückzugeben. Die MongoDB-Befehlsoption „getLastError“ bestimmt, wie die Replikationsaktualisierung mithilfe des optionalen „w“-Attributs durchgeführt wird.

Zum Beispiel diese Abfrage

db.runCommand({getLastError: 1, w: N, “wtimeout”: 5000});

erfordert, dass die Blockierung erfolgt, bis eine Anzahl von N Mitgliedern die letzte Schreiboperation repliziert hat. Wenn N verfügbar oder kleiner als 2 ist, wird die Abfrage zurückgegeben. Andernfalls, wenn der Wert für N gleich 2 ist, antwortet der Master, der dem primären entspricht, erst, nachdem einer seiner Slaves auf die letzte Operation repliziert wurde.

Das wtimeout Der Parameter dient im Wesentlichen dazu, die Zeit in Millisekunden festzulegen, nach der der Befehl getLastError eine Zeitüberschreitung ausführt und einen Fehler zurückgibt, bevor die letzte Option repliziert wurde.

So sehr Blockieren irgendwie vorteilhaft ist, hat es manchmal eine Einschränkung. Es verlangsamt die Lesevorgänge erheblich, insbesondere wenn Sie den „w“-Wert zu groß einstellen. Ich würde empfehlen, dass Sie den „w“-Wert entweder auf 2 oder 3 setzen, um die Sicherheit und Effizienz zu verbessern.

Leseeinstellung in MongoDB

Dies ist im Grunde die benachbarte Route, mit der die Client-Leseoperationen für den Replikatsatz durchgeführt werden. Das standardmäßige MongoDB-Setup konfiguriert die Lesevorgänge für die primäre Datenbank, da dies diejenige mit der neuesten Version des Dokuments ist, das Sie abrufen. Wie bereits erwähnt, besteht der größte Vorteil bei der Nutzung des Replikatsatzes darin, die Leistung unseres Datenbanksystems zu verbessern. Daher ist es ratsam, die Leseoperationen auf viele sekundäre Elemente zu verteilen, um die Latenzzeit für Anwendungen zu reduzieren, die nicht unbedingt aktuelle Daten benötigen. Es gibt jedoch wichtigere Gründe, warum Sie auch die Primäre als Ihre Grundeinstellung verwenden sollten:

  1. Aufrechterhaltung der Datenverfügbarkeit während des Failovers.
  2. Für geografisch verteilte Anwendungen stellt der primäre Server lokale Lesevorgänge für Clients im selben Rechenzentrum bereit.
  3. Die Front-End-Anwendungen nicht zu beeinträchtigen, insbesondere diejenigen, die Systemvorgänge ausführen.

Mongo.setReadPref() Methode

Diese Methode dient im Wesentlichen dazu, zu definieren, wie der Client alle Abfragen an Mitglieder des Replikatsatzes weiterleitet. Es braucht 2 Argumente, mode und tagSet.

Das Modus-Argument gibt die Lesepräferenz an, die entweder „primary“, „primaryPreferred“, „secondary“, „secondaryPreferred“ oder „Nearest“ sein kann.

Der TagSet-Modus gibt die benutzerdefinierte Lesepräferenz an. Sie können sie auch als Array von Objekten angeben. Ein Beispiel für die Einrichtung ist:

db.getMongo().setReadPref('primaryPreferred',
                          [ { "dc": "east", "use": "production" },
                            { "dc": "east", "use": "reporting" },
                            { "dc": "east" },
                            {}
                          ] )

Was hier passiert, ist Folgendes:Wenn der Client versucht, auf das erste Tag zuzugreifen und die Anfrage nicht durchgeht, wird er für die zweite Lesepräferenz entschieden.

Präferenzmodi lesen

  • Primär:Dies definiert, dass alle Lesevorgänge, die von einem bestimmten Replikatsatz gelesen werden, primär sind, und ist der standardmäßige bevorzugte Lesemodus.
  • PrimaryPreferred:Wenn nur der Primary nicht verfügbar ist, können die Leseoperationen von den Secondaries durchgeführt werden.
  • Sekundär:Alle Lesevorgänge werden von den sekundären Mitgliedern des Replikatsatzes ausgeführt.
  • SecondaryPreferred:Wenn nur kein Secondary verfügbar ist, können die Leseoperationen vom Primary durchgeführt werden.
  • Nächster:Mitglied mit der geringsten Netzwerklatenz wird unabhängig von seinem Typ für die Leseoperation ausgewählt.

Tag-Sets und ihre Konfiguration

Dies sind Optionen, mit denen Sie die Art und Weise modellieren können, wie Ihre Schreib- und Lesepräferenzen aussehen sollen. Sie werden im Replikatsatz-Konfigurationsobjekt gespeichert. Wenn Sie rs.conf().members ausführen, erhalten Sie dieses Objekt zurück:

[
    {
        "_id" : 0,
        "host" : "localhost:27018",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {
            
        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
    },
    {
        "_id" : 1,
        "host" : "127.0.0.1:27019",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {
            
        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
    }
]

Wie Sie sehen können, hat jedes Mitglied Tags-Attribute.

Der Hauptunterschied zwischen Read Preferences und Write Concern besteht darin, dass Ersteres den Wert eines Tags berücksichtigt, wenn ein Mitglied zum Lesen ausgewählt wird, während Letzteres dies nicht tut.

Angenommen, ein für einen Lesevorgang festgelegtes Tag ist wie folgt festgelegt:

{ "disk": "ssd", "use": "reporting" }

Ein Mitglied im Replikatsatz muss diese Tags erfüllen, damit der Lesevorgang durchlaufen wird. Also eine Konfiguration wie diese

{ "disk": "ssd", "use": "reporting", "rack": "a" }

wird die Abfrage erfüllen, während diese

{ "disk": "ssd", "use": "production", "rack": "k" }

wird die Abfrage nicht erfüllen.

Hinzufügen von Tags zu einer Set-Replik

Für Ihr ausgewähltes Mitglied in einem Replikatsatz können Sie mit der rs.conf()-Methode in MongoDB Tag-Sätze hinzufügen.

Angenommen, Sie haben ein Mitglied an Position 1 Ihres Replikat-Set-Arrays ausgewählt. Sie können Tag-Sets wie folgt hinzufügen.

conf = rs.conf()
conf.members[0].tags = { "dc": "NYK", "use": "production"  }
conf.members[1].tags = { "dc": "LON", "use": "reporting"  }
conf.members[2].tags = { "use": "production"  }
rs.reconfig(conf)

Bereitstellungsmuster für MongoDB-Replikatsatz

  1. Geografisch verteilter Replikatsatz – Verbessert die Redundanz von Daten und schützt Daten vor Fehlern wie Stromausfall. Die laufenden Instanzen befinden sich an mehreren Orten.
  2. Replica Set mit drei Mitgliedern - die grundlegende Standardarchitektur für ein Replikatset.
  3. Vier- oder mehrgliedriger Replikatsatz – Ermöglicht eine breitere Redundanz von Daten und unterstützt auch eine breitere Verteilung von Lesevorgängen im Replikatsatz.

Techniken zur Optimierung der MongoDB Replica Set-Bereitstellung

Ein ideales Replikatset erfordert eine gut durchdachte Architektur mit mindestens 3 Mitgliedern für ein Produktionssystem. Diese Bereitstellungsstrategien helfen Ihnen dabei, einen großartigen Replikatsatz zu ermöglichen.

  1. Verwenden Sie verzögerte und verborgene Mitglieder, um dedizierte Funktionen wie Berichterstellung und Sicherung zu unterstützen.
  2. Machen Sie die Anzahl der eingesetzten Mitglieder immer ungerade. Wie wir oben besprochen haben, ist für die Wahl einer Vorwahl eine ungerade Anzahl von Mitgliedern erforderlich. Stellen Sie daher sicher, dass Sie eine ungerade Zahl haben, und wenn nicht, können Sie immer einen Schiedsrichter hinzufügen.
  3. Bei leseintensiven Bereitstellungen müssen Sie die Last ausgleichen. Sie müssen daher Lesevorgänge auf die Sekundärseite verteilen, um die Leseleistung zu verbessern. Außerdem können Sie, wenn die Daten mit der Zeit wachsen, weitere Mitglieder hinzufügen und verteilen, aber denken Sie daran, dass Sie es so konfigurieren müssen, dass das vorrangige Design darin besteht, den Primären zu wählen.
  4. Berücksichtigen Sie immer die Fehlertoleranz. Dies bestimmt im Grunde, wie viele Mitglieder zu einem bestimmten Zeitpunkt nicht verfügbar sein können und wie viele übrig bleiben, um den Wahlprozess einer Vorwahl aufrechtzuerhalten. Wenn Sie keinen primären haben, akzeptiert der Replikatsatz leider keine Schreiboperationen.
  5. Fügen Sie dem bestehenden Replikatsatz neue Mitglieder hinzu, bevor Bedarf entsteht.
  6. Verwenden Sie Replikatsatz-Tag-Sets, um sicherzustellen, dass alle Vorgänge in bestimmten Rechenzentren repliziert werden. Sie können diese Tags auch beim Routing für die Lesevorgänge für bestimmte Bereitstellungsmaschinen verwenden.
  7. Stellen Sie die meisten Ihrer Mitglieder an einem Ort bereit, um den Rückschlag zu vermeiden, der durch die Netzwerkpartitionierung entsteht. Die Netzwerkpartitionierung kann das Ergebnis einer unterbrochenen Kommunikation zwischen Rechenzentren sein, wodurch der Replikationsprozess und der Prozess der Auswahl eines primären Servers behindert werden.
  8. Verteilen Sie Ihre Mitglieder aus Sicherheitsgründen geographisch, abgesehen davon, dass Sie einige verstecken. Sie können die Priorität von mindestens 2 oder 3 Mitgliedern auf null setzen, um zu verhindern, dass sie primär werden.
  9. Verwenden Sie Journaling, um Datenverlust zu vermeiden, der beispielsweise zu einem Stromausfall führen kann. Dadurch wird sichergestellt, dass Daten im Falle eines plötzlichen Herunterfahrens auf die Festplatte geschrieben werden.

Das Betriebsprotokoll (Oplog)

Das Oplog verwaltet eine Aufzeichnung der Masteroperationen, die auf die Slaves anzuwenden sind. Es wird in einer Datenbank namens local in der Sammlung oplog.$main gespeichert. Es wird erstellt, wenn Sie zum ersten Mal ein Replikatsatzmitglied starten. An der Obergrenze ist das Oplog für alle Speicher-Engines auf eine Größe von 50 GB beschränkt. Die Oplog-Größe kann von einer Standardeinstellung geändert werden. Wenn diese Größe zum Beispiel in 24 Stunden Betrieb erreicht wird, können die Secondaries während dieser Zeit nicht mehr bequem davon kopieren und können am Ende überhaupt nicht kopieren. Sie können die Größe des Oplogs mit der Option replSetResizeOplog ändern, dh

db.database({replSetResizeOplog:1, size: 16384})

Wenn Sie die Größe dieses Oplogs reduzieren, führt dies dazu, dass einige Daten entfernt werden. Die Hauptauswirkung davon im Replikatsatz besteht darin, dass Mitglieder, die mit diesem Knoten synchronisiert werden, veraltet sind. Daher müssen Sie diese Mitglieder erneut synchronisieren.

Workload-Muster, die eine große Oplog-Größe erfordern würden

  1. Auf mehrere Dokumente gleichzeitig aktualisieren. Die mehreren Aktualisierungsoperationen müssen in eine einzelne Operation übersetzt werden, um die Ergebnisse über die Knoten hinweg zu verbessern. Diese Operation wird einen großen Bereich des Oplog-Bereichs beanspruchen.
  2. Erhebliche Anzahl von In-Place-Updates. Dies geschieht im Allgemeinen, wenn Daten von Dokumenten aktualisiert werden, die nicht unbedingt die Größe dieses Dokuments erhöhen. Die Datenbank zeichnet eine große Anzahl von Operationen im Oplog auf, wodurch dessen Größe zunimmt.
  3. Löschungen entsprechen der gleichen Datenmenge wie Einfügungen. Dies geschieht, wenn Sie versuchen, eine Datenmenge zu löschen, die (fast) gleich der Datenmenge ist, die Sie einfügen. Diese Operation erhöht tendenziell die Größe des Oplogs.

Schlussfolgerung

Die Replikation ist ein wichtiger Aspekt von Datenbanken, den Entwickler verstehen müssen. Es sorgt für eine erhöhte Datenverfügbarkeit. Ihr MongoDB-Server kann beispielsweise aufgrund eines Stromausfalls ausfallen, aber Sie möchten trotzdem, dass Ihre Clients auf seine Daten zugreifen. Wenn Sie Daten auf einem anderen Server repliziert haben, können Ihre Clients weiterhin auf Daten von dort zugreifen, wenn der primäre Server ausfällt. Außerdem gibt es einen verbesserten Lastenausgleich, sodass statt dass alle Benutzer auf einen einzigen Server zugreifen, wir die Kompromisse beim Bereitstellen von Datenverkehr von sekundären Replikaten gesehen haben.