MongoDB is een NoSQL database die gebruik maakt van JSON-achtige documenten met dynamische schema’s. Als je met databases werkt, is het altijd goed om een noodplan te hebben voor het geval een van je databaseservers uitvalt. Je kunt de kans hierop verkleinen door gebruik te maken van een handige beheertool voor je WordPress site.

Daarom is het handig om veel kopieën van je gegevens te hebben, wat meteen ook vertragingen met lezen vermindert. Tegelijkertijd kan het de schaalbaarheid en beschikbaarheid van de database verbeteren. Dit is waar replicatie je kan helpen. Het wordt gedefinieerd als het synchroniseren van gegevens over meerdere databases.

In dit artikel duiken we in de verschillende opvallende aspecten van MongoDB replicatie, zoals de mogelijkheden en het mechanisme, om er een paar te noemen.

Wat is replicatie in MongoDB?

In MongoDB voeren replicaset de replicaties uit. Dit is een groep servers die door middel van replicatie dezelfde dataset onderhouden. Je kunt MongoDB replicatie zelfs gebruiken als onderdeel van load balancing. Hier kun je de schrijf- en leesbewerkingen verdelen over alle instanties, gebaseerd op de use case.

Wat is een MongoDB replicaset?

Elke instantie van MongoDB die deel uitmaakt van een bepaalde replicaset is een member. Elke replicaset moet een primaire member hebben en tenminste één secundaire member.

De primaire member is het primaire toegangspunt voor transacties met de replicaset. Deze is ook de enige member die schrijfoperaties kan accepteren. Replicatie kopieert eerst het oplog (operations log) van de primaire member. Vervolgens herhaalt het de gelogde veranderingen op de respectieve datasets van de secondaries. Elke replicaset kan dus maar één primaire member tegelijk hebben, omdat verschillende primaries die schrijfoperaties ontvangen gegevensconflicten kunnen veroorzaken.

Gewoonlijk bevragen de applicaties alleen de primaire member voor schrijf- en leesbewerkingen. Je kunt je opstelling zo ontwerpen dat er van één of meer secundaire members wordt gelezen. Asynchrone gegevensoverdracht kan ertoe leiden dat de leesbewerkingen van de secundaire nodes oude gegevens leveren. Zo’n opstelling is dus niet ideaal voor elk gebruik.

Replicaset features

Het automatische failovermechanisme onderscheidt de replicasets van MongoDB van de concurrentie. Bij het ontbreken van een primary kiest een geautomatiseerde verkiezing onder de secundaire nodes een nieuwe primary.

MongoDB replicaset vs MongoDB cluster

Een MongoDB replicaset maakt verschillende kopieën van dezelfde dataset over de replicaset nodes. Het primaire doel van een replica set is:

  • Een ingebouwde backupoplossing te bieden
  • De beschikbaarheid van gegevens vergroten

Een MongoDB cluster is helemaal anders. Het verdeelt de gegevens over vele nodes via een shardsleutel. Dit proces fragmenteert de gegevens in vele stukken, shards genaamd. Vervolgens kopieert het elke shard naar een andere node. Een cluster is bedoeld om grote gegevenssets en operaties met hoge doorvoer te ondersteunen. Dit wordt bereikt door de workload horizontaal te schalen.

Dit is het verschil tussen een replicaset en een cluster, in makkelijk te begrijpen taal:

  • Een cluster verdeelt de workload en slaat fragmenten van gegevens (shards) op over vele servers.
  • Een replicaset dupliceert de gegevensset volledig.

Met MongoDB kun je deze functionaliteiten combineren door een sharded cluster te maken. Hier kun je elke shard repliceren naar een secundaire server. Hierdoor kan een shard een hoge redundantie en gegevensbeschikbaarheid bieden.

Het onderhouden en opzetten van een replicaset kan technisch belastend en tijdrovend zijn. En het vinden van de juiste hostingdienst? Misschien nog wel lastiger! Met zoveel potentiële kandidaten, is het gemakkelijk om uren kwijt te zijn aan onderzoek, in plaats van je bedrijf op te bouwen.

Laat me je kort informeren over een tool dat dit alles en nog veel meer doet, zodat jij weer verder kunt met je dienst/product.

De Applicatie Hosting oplossing van Kinsta, waarop al meer dan 55.000 developers vertrouwen, kun je in slechts 3 eenvoudige stappen gebruiken. Als dat te mooi klinkt om waar te zijn, zijn hier nog enkele voordelen van het gebruik van Kinsta:

  • Geniet van betere prestaties met Kinsta’s interne verbindingen: Vergeet je struggles met gedeelde databases. Stap over op dedicated databases met interne verbindingen die geen limieten hebben op aantal query’s of rijen. Kinsta is sneller, veiliger en brengt je niet in rekening voor interne bandbreedte/verkeer.
  • Een featureset op maat gemaakt voor developers: Schaal je applicatie op het robuuste platform dat Gmail, YouTube en Google Search ondersteunt. Wees gerust, je bent hier in de veiligste handen.
  • Profiteer van ongeëvenaarde snelheden met een datacenter naar keuze: Kies de regio die het beste werkt voor jou en je klanten. Met meer dan 25 datacenters om uit te kiezen, zorgen Kinsta’s 260+ PoP’s zorgen voor maximale snelheid en een wereldwijde aanwezigheid voor je website.

Probeer Kinsta’s Applicatie Hosting oplossing vandaag nog gratis uit!

Hoe werkt replicatie in MongoDB?

In MongoDB stuur je schrijfoperaties naar de primaire server (node). De primary (primaire server) wijst de operaties toe aan secundaire servers, waardoor de gegevens worden gerepliceerd.

Dit is een stroomschema van hoe replicatie werkt in MongoDB, voor 3 nodes (1 primary, 2 secundair)
MongoDB replicatieproces illustratie (Afbeelding Bron: MongoDB)

Drie soorten MongoDB nodes

Van de drie typen MongoDB nodes zijn er twee al eerder naar voren gekomen: primaire en secundaire nodes. Het derde type MongoDB node dat van pas komt bij replicatie is een arbiter. De arbiter node heeft geen kopie van de gegevensset en kan ook geen primary worden. De arbiter neemt echter wel deel aan verkiezingen voor de primary.

We hebben eerder vermeld wat er gebeurt als de primaire node uitvalt, maar wat als de secundaire nodes weg zijn? In dat scenario wordt de primaire node secundair en wordt de database onbereikbaar.

Verkiezing van members

De verkiezingen kunnen plaatsvinden in de volgende scenario’s:

  • Initialiseren van een replicaset
  • Verlies van connectiviteit met het primaire node (dat kan worden gedetecteerd door heartbeats)
  • Onderhoud van een replicaset met behulp van rs.reconfig of stepDown methoden
  • Toevoegen van een nieuw node aan een bestaande replicaset

Een verzameling replica’s kan maximaal 50 members hebben, maar slechts 7 of minder kunnen stemmen in een verkiezing.

De gemiddelde tijd voordat een cluster een nieuwe primary kiest mag niet langer zijn dan 12 seconden. Het verkiezingsalgoritme zal proberen de secundaire met de hoogste prioriteit beschikbaar te stellen. Tegelijkertijd kunnen de members met een prioriteitswaarde van 0 geen primary worden en doen ze niet mee aan de verkiezing.

Dit is een diagram dat een secundair node weergeeft dat na de verkiezing een primair node wordt in MongoDB.
Secundaire node die primair wordt (Beeldbron: Medium)

De write concern

Voor duurzaamheidsdoeleinden hebben schrijfoperaties een framework om de gegevens in een bepaald aantal nodes te kopiëren. Je kunt hiermee zelfs feedback bieden aan de cliënt. Dit framework staat ook bekend als de “write concern.” Het bevat gegevensdragende members die een write concern moeten bevestigen voordat de operatie als geslaagd terugkeert. In het algemeen hebben de replicasets een waarde van 1 als write concern. Dus alleen de primaire moet het schrijven bevestigen voordat de write concern bevestiging terugkomt.

Je kunt zelfs het aantal members verhogen dat nodig is om de schrijfoperatie te bevestigen. Er is geen maximum aan het aantal members dat je kunt hebben. Maar als het aantal hoog is, moet je rekening houden met een hoge vertraging. Dit komt doordat de client moet wachten op bevestiging van alle members. Ook kun je de write concern van de “majority” instellen.” Dit zorgt voor goedkeuring nadat meer dan de helft van de members hebben bevestigd.

Leesvoorkeur

Voor de leesoperaties kun je de leesvoorkeur opgeven die beschrijft hoe de database de query naar de members van de replicaset stuurt. In het algemeen ontvangt de primaire node de leesoperatie, maar de client kan een leesvoorkeur opgeven om de leesoperaties naar secundaire nodes te sturen. Hieronder staan de opties voor de leesvoorkeur:

  • primaryPreferred: Gewoonlijk komen de leesbewerkingen van de primaire node, maar als dit niet beschikbaar is worden de gegevens van de secundaire nodes gehaald.
  • primary: Alle leesbewerkingen komen van de primaire node.
  • secundary: Alle leesbewerkingen worden uitgevoerd door de secundaire nodes.
  • nearest: Hier worden de leesverzoeken gerouteerd naar de dichtstbijzijnde bereikbare node, dat kan worden gedetecteerd door het commando ping uit te voeren. Het resultaat van leesbewerkingen kan van elk member van de replicaset komen, ongeacht of het de primaire of de secundaire is.
  • secondaryPreferred: Hier komen de meeste leesbewerkingen van de secundaire nodes, maar als geen van hen beschikbaar is, worden de gegevens van de primaire node gehaald.

Replicatieset datasynchronisatie

Om actuele kopieën van de gedeelde gegevensset te onderhouden, repliceren of synchroniseren secundaire members van een replicaset gegevens van andere members.

MongoDB maakt gebruik van twee vormen van datasynchronisatie. Initiële synchronisatie om nieuwe members te vullen met de volledige dataset en replicatie om lopende wijzigingen in de volledige dataset uit te voeren.

Initiële synchronisatie

Tijdens de initiële synchronisatie voert een secundaire node het commando init sync uit om alle gegevens van de primaire node te synchroniseren met een andere secundair node dat de meest recente gegevens bevat. Daarom gebruikt de secundaire node consequent de functie tailable cursor om de nieuwste oplogs binnen de verzameling local.oplog.rs van het primaire node op te vragen en past deze bewerkingen toe binnen deze oplogs.

Vanaf MongoDB 5.2 kunnen initiële synchronisaties gebaseerd zijn op bestandskopieën of logisch.

Logische synchronisatie

Wanneer je een logische sync uitvoert, doet MongoDB het volgende:

  1. Ontwikkelt alle collectie-indexen terwijl de documenten voor elke collectie worden gekopieerd.
  2. Dupliceert alle databases behalve de local database. mongod scant elke collectie in alle sourcedatabases en voegt alle gegevens in de duplicaten van deze collecties in.
  3. Voert alle wijzigingen op de gegevensverzameling uit. Door gebruik te maken van de oplog van de source, werkt de mongod zijn gegevensset bij om de huidige state van de replicaset weer te geven.
  4. Haalt nieuw toegevoegde oplog records op tijdens het kopiëren van gegevens. Zorg ervoor dat de targetmember voldoende schijfruimte heeft in de lokale database om deze oplog records voorlopig op te slaan voor de duur van deze gegevenskopiefase.

Wanneer de initiële synchronisatie voltooid is, gaat de member over van STARTUP2 naar SECONDARY .

Op bestandskopie gebaseerde initiële synchronisatie

Je kunt dit alleen uitvoeren als je MongoDB Enterprise gebruikt. Dit proces voert de initiële sync uit door de bestanden op het bestandssysteem te dupliceren en te verplaatsen. Deze synchronisatiemethode kan in sommige gevallen sneller zijn dan een logische initiële synchronisatie. Houd in gedachten dat op bestandskopie gebaseerde initiële sync kan leiden tot onnauwkeurige tellingen als je de count() methode uitvoert zonder een query predicaat.

Maar ook deze methode heeft zijn beperkingen:

  • Tijdens een initiële synchronisatie op basis van bestandskopieën kun je niet schrijven naar de lokale database van de member die gesynchroniseerd wordt. Je kunt ook geen backup maken van het member waarnaar gesynchroniseerd wordt of van het member waarvan gesynchroniseerd wordt.
  • Bij het gebruik van de versleutelde storage engine gebruikt MongoDB de bronsleutel om de bestemming te versleutelen.
  • Je kunt alleen een initiële synchronisatie uitvoeren vanaf één bepaalde member tegelijk.

Replicatie

Secundaire members repliceren gegevens consistent na de initiële synchronisatie. Secundaire members dupliceren de oplog van hun sync van de bron en voeren deze operaties uit in een asynchroon proces.

Secundaire members zijn in staat hun sync van de bron automatisch aan te passen als dat nodig is, gebaseerd op de veranderingen in de pingtijd en de state van de replicatie van andere members.

Streamingreplicatie

Vanaf MongoDB 4.4 stuurt sync van bronnen een continue stroom oplog entries naar hun synchroniserende secondaries. Streamingreplicatie vermindert de replicatievertraging in netwerken met hoge belasting en hoge latency. Het kan verder:

  • Het risico verkleinen dat schrijfoperaties met w:1 verloren gaan door primaire failover.
  • De staleness voor reads van secondaries verminderen.
  • De latency op schrijfoperaties verminderen met w:“majority” en w:>1. Elke write concern die moet wachten op replicatie.
Multithreaded replicatie

MongoDB gebruikte operaties om in batches door meerdere threads te laten lopen om de concurrency te verbeteren. MongoDB groepeert de batches op document ID en geeft elke groepoperatie een andere thread.

MongoDB voert schrijfoperaties op een bepaald document altijd uit in de oorspronkelijke schrijfvolgorde. Dit is veranderd in MongoDB 4.0.

Vanaf MongoDB 4.0 zullen leesbewerkingen die gericht zijn op secondaries en geconfigureerd zijn met een lees concern level van “majority” of “local” lezen van een WiredTiger snapshot van de gegevens als het lezen plaatsvindt op een secondary waar de replicatiebatches worden toegepast. Lezen van een snapshot garandeert een consistent beeld van de gegevens, en laat het lezen gelijktijdig plaatsvinden met de lopende replicatie zonder dat een lock nodig is.

Daarom hoeven secundaire reads die deze lees concern niveau nodig hebben niet langer te wachten tot de replicatiebatches worden toegepast en kunnen ze worden afgehandeld wanneer ze worden ontvangen.

Zo maak je een MongoDB replicaset

Zoals eerder vermeld, handelt MongoDB replicatie af door middel van replicasets. In de volgende paragrafen belichten we een paar methoden die je kunt gebruiken om replicasets aan te maken voor jouw applicatie.

Methode 1: Aanmaken van een nieuwe MongoDB replicaset op Ubuntu

Voordat we beginnen, moet je ervoor zorgen dat je tenminste drie servers hebt waarop Ubuntu 20.04 draait en waarop MongoDB is geïnstalleerd.

Om een replicaset op te zetten is het essentieel om een adres op te geven waar elk member van de replicaset kan worden bereikt door anderen in de set. In dit geval houden we drie members in de set. We kunnen weliswaar IP adressen gebruiken, maar dat is niet aan te raden omdat de adressen onverwacht kunnen veranderen. Een beter alternatief kan het gebruik van de logische DNS hostnamen zijn bij het configureren van replicasets.

We kunnen dit doen door voor elk replicatiemember het subdomein te configureren. Hoewel dit ideaal kan zijn voor een productieomgeving, wordt in deze sectie uitgelegd hoe we DNS resolutie kunnen configureren door de respectievelijke hostsbestanden van elke server te bewerken. Dit bestand staat ons toe leesbare hostnamen toe te wijzen aan numerieke IP adressen. Dus als je IP adres ooit verandert, hoef je alleen maar de hostsbestanden op de drie servers bij te werken in plaats van de replicaset helemaal opnieuw te configureren!

Meestal wordt hosts opgeslagen in de map /etc/. Herhaal de onderstaande commando’s voor elk van je drie servers:

sudo nano /etc/hosts

In het bovenstaande commando gebruiken we nano als onze teksteditor, je kunt echter elke teksteditor gebruiken die je wil. Voeg na de eerste paar regels, die de localhost configureren, een regel toe voor elk member van de replicaset. Deze regels hebben de vorm van een IP adres gevolgd door een menselijk leesbare naam naar keuze. Je kunt ze noemen wat je wilt, maar zorg ervoor dat ze beschrijvend zijn, zodat je elk member kunt onderscheiden. Voor deze tutorial gebruiken we de onderstaande hostnamen:

  • mongo0.replset.member
  • mongo1.replset.member
  • mongo2.replset.member

Met deze hostnamen zouden je /etc/hosts bestanden er ongeveer zo uitzien als de volgende gemarkeerde regels:

Dit is een momentopname van de /etc/hostsbestanden die de hostnamen samen met het IP adres bevatten.
Hostnamen illustratie

Sla het bestand op en sluit het.

Na het configureren van de DNS resolutie voor de replicaset, moeten we de firewallregels bijwerken zodat ze met elkaar kunnen communiceren. Voer het volgende ufw commando uit op mongo0 om mongo1 toegang te geven tot poort 27017 op mongo0:

sudo ufw allow from mongo1_server_ip to any port 27017

Voer in plaats van de parameter mongo1_server_ip het werkelijke IP adres van je mongo1 server in. Als je de Mongo instantie op deze server hebt bijgewerkt om een niet-standaard poort te gebruiken, moet je 27017 aanpassen aan de poort die je MongoDB instantie gebruikt.

Voeg nu een andere firewall regel toe om mongo2 toegang te geven tot dezelfde poort:

sudo ufw allow from mongo2_server_ip to any port 27017

Voer in plaats van de parameter mongo2_server_ip het werkelijke IP adres van je mongo2 server in. Werk dan de firewall regels voor je andere twee servers bij. Voer de volgende commando’s uit op de mongo1 server en zorg ervoor dat je de IP adressen in plaats van de server_ip parameter aanpast aan die van respectievelijk mongo0 en mongo2:

sudo ufw allow from mongo0_server_ip to any port 27017
sudo ufw allow from mongo2_server_ip to any port 27017

Voer tot slot deze twee commando’s uit op mongo2. Let er opnieuw op dat je voor elke server de juiste IP adressen invoert:

sudo ufw allow from mongo0_server_ip to any port 27017
sudo ufw allow from mongo1_server_ip to any port 27017

Je volgende stap is om het configuratiebestand van elke MongoDB instantie bij te werken om externe verbindingen toe te staan. Om dit toe te staan moet je het configuratiebestand in elke server aanpassen om het IP adres weer te geven en de replicaset aan te geven. Hoewel je elke gewenste teksteditor kunt gebruiken, gebruiken wij opnieuw de nano teksteditor. Laten we de volgende wijzigingen aanbrengen in elk mongod.conf bestand.

Op mongo0:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo0.replset.member# replica set
replication:
replSetName: "rs0"

Op mongo1:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo1.replset.member
replication:
replSetName: "rs0"

Op mongo2:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo2.replset.member
replication:
replSetName: "rs0"
sudo systemctl restart mongod

Hiermee heb je replicatie ingeschakeld voor de MongoDBn instantie van elke server.

Je kunt nu de replicaset initialiseren met de methode rs.initiate(). Deze methode hoeft maar op één MongoDB instantie in de replicaset te worden uitgevoerd. Zorg ervoor dat de naam en het member van de replicaset overeenkomen met de configuraties die je eerder in elk configuratiebestand hebt gemaakt.

rs.initiate(
  {
    _id: "rs0",
    members: [
      { _id: 0, host: "mongo0.replset.member" },
      { _id: 1, host: "mongo1.replset.member" },
      { _id: 2, host: "mongo2.replset.member" }
    ]
  }
)

Als de methode “ok”: 1 retourneert in de uitvoer, betekent dit dat de replicaset correct is gestart. Hieronder staat een voorbeeld van hoe de uitvoer er uit zou moeten zien:

 "ok": 1,
  "$clusterTime": {
    "clusterTime": Timestamp(1612389071, 1),
    "signature": {
      "hash": BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
      "keyId": NumberLong(0)
    }
  },
  "operationTime": Timestamp(1612389071, 1)
}

MongoDB server afsluiten

Je kunt een MongoDB server afsluiten met de methode db.shutdownServer(). Hieronder staat de syntaxis voor hetzelfde. Zowel force als timeoutsecs zijn optionele parameters.

db.shutdownServer({
  force: <boolean>,
  timeoutSecs: <int>
})

Deze methode kan mislukken als het mongod replicasetmember bepaalde operaties uitvoert als index builds. Om de bewerkingen te onderbreken en het member te dwingen af te sluiten, kun je de booleaanse parameter force invoeren op true.

MongoDB opnieuw opstarten met –replSet

Om de configuratie opnieuw in te stellen, zorg je ervoor dat elke node in je replicaset is gestopt. Verwijder dan de lokale database voor elk node. Start hem opnieuw met de –replSetvlag en voer rs.initiate() uit op slechts één mongod instantie voor de replicaset.

mongod --replSet "rs0"

rs.initiate() kan een optioneel replicaset configuratiedocument nemen, namelijk:

  • De optie Replication.replSetName of de optie —replSet om de naam van de replicaset te specificeren in het veld _id.
  • De array van members, die een document bevat voor elk member van de replicaset.

De methode rs.initiate() brengt een verkiezing op gang en kiest een van de members tot de primaire.

Members toevoegen aan replicaset

Om members aan de set toe te voegen, start je mongo instanties op verschillende machines. Start vervolgens een mongo client en gebruik het commando rs.add().

Het rs.add() commando heeft de volgende basissyntaxis:

rs.add(HOST_NAME:PORT)

Bijvoorbeeld,

Stel dat mongo1 je Mongo instantie is, en dat deze luistert op poort 27017. Gebruik het Mongo client commando rs.add() om deze instantie toe te voegen aan de replicaset.

rs.add("mongo1:27017")

Pas als je verbonden bent met het primaire node kun je een mongo instantie toevoegen aan de replicaset. Om te controleren of je verbonden bent met de primaire, gebruik je het commando db.isMaster().

Members te verwijderen

Om een member te verwijderen kunnen we rs.remove() gebruiken

Om dit te doen, sluit je eerst de mongod instantie die je wilt verwijderen af met de hierboven besproken methode db.shutdownServer().

Maak vervolgens verbinding met de huidige primaire replicaset. Om de huidige primary te bepalen gebruik je db.hello() terwijl je verbonden bent met een member van de replicaset. Zodra je de primary hebt bepaald, voer je een van de volgende commando’s uit:

rs.remove("mongodb-node-04:27017")
rs.remove("mongodb-node-04")
Dit is een snapshot van de uitvoer na het uitvoeren van de opdracht rs.remove().
De bovenstaande afbeelding laat zien dat het node met succes uit de replicaset is verwijderd. (Beeldbron: Bmc)

Als de replicaset een nieuwe primary moet kiezen, kan MongoDB de verbinding met de shell kort verbreken. In dit scenario zal het automatisch weer verbinding maken. Ook kan het een DBClientCursor::init call() failed error weergeven, ook al slaagt het commando.

Methode 2: Een MongoDB replicaset instellen voor deployment en testen

In het algemeen kun je replicasets voor testen instellen met RBAC ingeschakeld of uitgeschakeld. In deze methode stellen we replicasets in met de toegangscontrole uitgeschakeld om ze in een testomgeving te deployen.

Maak eerst mappen aan voor alle instanties die deel uitmaken van de replicaset met het volgende commando:

mkdir -p /srv/mongodb/replicaset0-0  /srv/mongodb/replicaset0-1 /srv/mongodb/replicaset0-2

Dit commando maakt mappen aan voor drie MongoDB instanties replicaset0-0, replicaset0-1, en replicaset0-2. Start nu de MongoDB instanties voor elk van hen met de volgende reeks commando’s:

Voor Server 1:

mongod --replSet replicaset --port 27017 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

Voor Server 2:

mongod --replSet replicaset --port 27018 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

Voor Server 3:

mongod --replSet replicaset --port 27019 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

De parameter –oplogSize wordt gebruikt om te voorkomen dat de machine tijdens de testfase overbelast raakt. Hij helpt de hoeveelheid schijfruimte die elke schijf inneemt te beperken.

Maak nu verbinding met een van de instanties met de Mongo shell door verbinding te maken met het onderstaande poortnummer.

mongo --port 27017

We kunnen het commando rs.initiate() gebruiken om het replicatieproces te starten. Je moet de parameter hostname vervangen door de naam van je systeem.

rs conf = {

  _id: "replicaset0",

  members: [

    {  _id: 0,  host: "<hostname>:27017},

    {  _id: 1,  host: "<hostname>:27018"},

    {  _id: 2,  host: "<hostname>:27019"}

   ] }

Je kunt nu het configuratieobjectbestand doorgeven als parameter voor het initiate commando en het als volgt gebruiken:

rs.initiate(rsconf)

En dat is alles! Je hebt met succes een MongoDB replicaset gemaakt voor ontwikkelings– en testdoeleinden.

Methode 3: Een standalone instantie transformeren naar een MongoDB replicaset

MongoDB staat zijn gebruikers toe om hun standalone instanties om te zetten in replicasets. Terwijl standalone instanties meestal worden gebruikt voor de test- en ontwikkelingsfase, maken replicasets deel uit van de productieomgeving.

Om te beginnen sluiten we onze mongod instantie af met het volgende commando:

db.adminCommand({"shutdown":"1"})

Start je instantie opnieuw op door de parameter –repelSet in je commando te gebruiken om de replicaset die je gaat gebruiken te specificeren:

mongod --port 27017 – dbpath /var/lib/mongodb  --replSet replicaSet1 --bind_ip localhost,<hostname(s)|ip address(es)>

Je moet de naam van je server opgeven samen met het unieke adres in het commando.

Verbind de shell met je MongoDB instantie en gebruik het initiate commando om het replicatieproces te starten en de instantie met succes om te zetten naar een replicaset. Je kunt alle basisbewerkingen zoals het toevoegen of verwijderen van een instantie uitvoeren met de volgende commando’s:

rs.add(“<host_name:port>”)
rs.remove(“host-name”)

Daarnaast kun je de status van je MongoDB replicaset controleren met de commando’s rs.status() en rs.conf().

Methode 4: MongoDB Atlas – een eenvoudiger alternatief

Replicatie en sharding kunnen samenwerken om een zogenaamd sharded cluster te vormen. Hoewel het opzetten en configureren nogal tijdrovend kan zijn, is MongoDB Atlas een beter alternatief dan de eerder genoemde methoden.

Het automatiseert je replicasets, waardoor het proces eenvoudig te implementeren is. Het kan globale sharded replicasets implementeren met een paar klikken, waardoor disaster recovery, eenvoudiger beheer, datalokalisatie en multi-regio deployments mogelijk worden.

In MongoDB Atlas moeten we clusters maken – dat kan een replicaset zijn, of een sharded cluster. Voor een bepaald project is het aantal nodes in een cluster in andere regio’s beperkt tot een totaal van 40.

Dit is exclusief de vrije of gedeelde clusters en de Google cloudregio’s die met elkaar communiceren. Het totale aantal nodes tussen twee willekeurige regio’s moet aan deze beperking voldoen. Als er bijvoorbeeld een project is waarin:

  • Regio A 15 nodes heeft .
  • Regio B 25 nodes heeft
  • Regio C 10 nodes heeft

We kunnen slechts 5 extra nodes aan regio C toewijzen als,

  1. Regio A+ Regio B = 40; voldoet aan de beperking dat 40 het maximaal toegestane aantal nodes is.
  2. Regio B+ Regio C = 25+10+5 (Extra nodes toegewezen aan C) = 40; voldoet aan de beperking dat 40 het maximum aantal toegestane nodes is.
  3. Regio A+ Regio C =15+10+5 (Extra nodes toegewezen aan C) = 30; voldoet aan de beperking dat 40 het maximum aantal toegestane nodes is.

Als we 10 extra nodes aan regio C toekennen, zodat regio C 20 nodes heeft, dan zijn Regio B + Regio C = 45 nodes. Dit zou de gegeven beperking overschrijden, zodat je mogelijk geen multi-regio cluster kunt maken.

Als je een cluster aanmaakt, maakt Atlas een netwerkcontainer in het project voor de cloudprovider als die er eerder nog niet was. Om een replicasetcluster in MongoDB Atlas aan te maken, voer je het volgende commando uit in Atlas CLI:

atlas clusters create [name] [options]

Zorg ervoor dat je een beschrijvende clusternaam opgeeft, want die kan niet meer veranderd worden nadat het cluster is aangemaakt. Het argument kan ASCII letters, cijfers en koppeltekens bevatten.

Er zijn verschillende opties beschikbaar voor het aanmaken van clusters in MongoDB, gebaseerd op je eisen. Als je bijvoorbeeld een continue cloudbackup voor je cluster wilt, stel dan --backup in op true.

Omgaan met replicatievertraging

Replicatievertraging kan behoorlijk vervelend zijn. Het is een vertraging tussen een bewerking op de primary en de applicatie van die bewerking van de oplog op de secondary. Als je bedrijf te maken heeft met grote gegevensverzamelingen, is een vertraging binnen een bepaalde drempel te verwachten. Soms kunnen echter ook externe factoren bijdragen en de vertraging vergroten. Om te profiteren van een snelle replicatie moet je ervoor zorgen dat:

  1. Je je netwerkverkeer in een stabiele en voldoende bandbreedte routeert. Netwerklatency speelt een grote rol bij het beïnvloeden van je replicatie, en als het netwerk onvoldoende is om aan de behoeften van het replicatieproces te voldoen, zullen er vertragingen optreden bij het repliceren van gegevens in de hele replicaset.
  2. Je hebt voldoende schijfdoorvoer. Als het bestandssysteem en het schijfapparaat op de secondary niet in staat zijn om gegevens zo snel naar de schijf te flushen als de primary, dan zal de secondary moeite hebben om het bij te houden. Daarom verwerken de secundaire nodes de schrijfverzoeken langzamer dan het primaire node. Dit is een veel voorkomend probleem in de meeste multi-tenant systemen, inclusief gevirtualiseerde instanties en grootschalige implementaties.
  3. Je vraagt om een schrijfbevestiging na een interval om de secondaries de gelegenheid te geven om de primary in te halen, vooral wanneer je een bulk load operatie of data ingestion wilt uitvoeren die een groot aantal schrijfbewerkingen naar de primary vereist. De secondaries zullen de oplog niet snel genoeg kunnen lezen om de veranderingen bij te houden; vooral bij niet-erkende write concerns.
  4. Je identificeert de lopende achtergrondtaken. Bepaalde taken zoals cron jobs, serverupdates, en beveiligingscontroles kunnen onverwachte effecten hebben op het netwerk of schijfgebruik, en vertragingen veroorzaken in het replicatieproces.

Als je niet zeker weet of er sprake is van een replicatievertraging in je applicatie, geen nood – de volgende sectie bespreekt troubleshootingstrategieën!

MongoDB replicasets troubleshooten

Je hebt je replicasets met succes ingesteld, maar je merkt dat je gegevens inconsistent zijn tussen de servers. Dit is zeer alarmerend voor grootschalige bedrijven, maar met snelle troubleshootingmethoden kun je de oorzaak vinden of het probleem zelfs verhelpen! Hieronder staan enkele veelvoorkomende strategieën voor het oplossen van problemen met replicasets die van pas kunnen komen:

Controleer de replicatiestatus

We kunnen de huidige status van de replicaset en de status van elke member controleren door het volgende commando uit te voeren in een mongosh sessie die verbonden is met de primary van een replicaset.

 rs.status()

Controleer de replicatievertraging

Zoals eerder besproken kan replicatievertraging een serieus probleem zijn, omdat het maakt dat “lagged” (trage) members niet in aanmerking komen om snel primary te worden en het vergroot de kans dat gedistribueerde leesbewerkingen inconsistent zijn. We kunnen de huidige lengte van het replicatielog controleren met het volgende commando:

rs.printSecondaryReplicationInfo()

Dit geeft de waarde syncedTo terug, wat de tijd is waarop voor elk member de laatste oplog entry naar de secondary is geschreven. Hier is een voorbeeld om hetzelfde te demonstreren:

source: m1.example.net:27017
    syncedTo: Mon Oct 10 2022 10:19:35 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary
source: m2.example.net:27017
    syncedTo: Mon Oct 10 2022 10:19:35 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary

Een vertraagde member kan je met 0 seconden vertraging zien als de inactiviteitsperiode op de primary groter is dan de members[n].secondaryDelaySecs waarde.

Test verbindingen tussen alle members

Elke member van een replicaset moet verbinding kunnen maken met elk andere member. Controleer altijd de verbindingen in beide richtingen. Meestal verhinderen firewallconfiguraties of netwerktopologieën normale en vereiste verbindingen die de replicatie kunnen blokkeren.

Laten we bijvoorbeeld aannemen dat de mongod instantie zich bindt aan zowel localhost als hostname ‘ExampleHostname’ die geassocieerd is met het IP adres 198.41.110.1:

mongod --bind_ip localhost, ExampleHostname

Om verbinding te maken met deze instantie moeten externe cliënten de hostnaam of het IP adres opgeven:

mongosh --host ExampleHostname
mongosh --host 198.41.110.1

Als een replicaset bestaat uit drie members, m1, m2, en m3, die de standaardpoort 27017 gebruiken, moet je de verbinding testen zoals hieronder:

Op m1:

mongosh --host m2 --port 27017
mongosh --host m3 --port 27017

Op m2:

mongosh --host m1 --port 27017
mongosh --host m3 --port 27017

Op m3:

mongosh --host m1 --port 27017
mongosh --host m2 --port 27017

Als een verbinding in welke richting dan ook mislukt, zou je je firewallconfiguratie moeten controleren en opnieuw configureren om de verbindingen toe te staan.

Zorgen voor veilige communicatie met keyfile authenticatie

Standaard vertrouwt de authenticatie van sleutelbestanden in MongoDB op het salted challenge response authenticatiemechanisme (SCRAM). Om dit te doen moet MongoDB de door de gebruiker verstrekte referenties lezen en valideren, die een combinatie bevatten van de gebruikersnaam, het wachtwoord en de authenticatie database waar de specifieke MongoDB instantie van op de hoogte is. Dit is het exacte mechanisme dat gebruikt wordt om gebruikers te authentiseren die een wachtwoord opgeven bij het verbinden met de database.

Wanneer je authenticatie in MongoDB inschakelt, wordt automatisch RBAC (Role-Based Access Control) ingeschakeld voor de replicaset, en krijgt de gebruiker een of meer rollen die zijn toegang tot databasebronnen bepalen. Wanneer RBAC is ingeschakeld, betekent dit dat alleen de geldige geauthentiseerde Mongo gebruiker met de juiste privileges toegang heeft tot de resources op het systeem.

Het sleutelbestand fungeert als een gedeeld wachtwoord voor elke member in het cluster. Hierdoor kan elke Mongo instantie in de replicaset de inhoud van het sleutelbestand gebruiken als het gedeelde wachtwoord voor de authenticatie van andere members in de deployment.

Alleen de mongod instanties met het juiste sleutelbestand kunnen toetreden tot de replicaset. De lengte van een sleutel moet liggen tussen 6 en 1024 tekens en mag alleen tekens in de base64 set bevatten. Merk op dat MongoDB bij het lezen van sleutels de spaties stript.

Je kunt een sleutelbestand genereren door verschillende methoden te gebruiken. In deze tutorial gebruiken we openssl om een complexe string van 1024 willekeurige tekens te genereren om te gebruiken als gedeeld wachtwoord. Vervolgens wordt chmod gebruikt om de bestandspermissies te wijzigen zodat alleen de eigenaar van het bestand leesrechten krijgt. Vermijd het opslaan van het sleutelbestand op opslagmedia die gemakkelijk losgekoppeld kunnen worden van de hardware waarop de mongod instanties staan, zoals een USB stick of een netwerkopslagapparaat. Hieronder staat het commando om een sleutelbestand te genereren:

openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>

Kopieer vervolgens het sleutelbestand naar elke member van de replicatieset. Zorg ervoor dat de gebruiker die de mongod instanties draait de eigenaar is van het bestand en toegang heeft tot het sleutelbestand. Nadat je het bovenstaande hebt gedaan, sluit je alle members van de replicaset af, te beginnen met de secondaries. Als alle secondaries offline zijn, kun je doorgaan met het afsluiten van de primary. Het is essentieel om deze volgorde aan te houden om mogelijke rollbacks te voorkomen. Sluit nu de mongod instantie af met het volgende commando:

use admin
db.shutdownServer()

Nadat het commando is uitgevoerd, zullen alle members van de replicaset offline zijn. Start nu elk member van de replica set opnieuw op met toegangscontrole ingeschakeld.

Start voor elk member van de replicaset de mongod instantie met de instelling van het configuratiebestand security.keyFile of de commandoregeloptie --keyFile.

Als je een configuratiebestand gebruikt, gebruik dan

  • security.keyFile ingesteld op het pad van het sleutelbestand, en
  • replication.replSetName ingesteld op de naam van de replicaset.
security:
  keyFile: <path-to-keyfile>
replication:
  replSetName: <replicaSetName>
net:
   bindIp: localhost,<hostname(s)|ip address(es)>

Start de mongod instantie met behulp van het configuratiebestand:

mongod --config <path-to-config-file>

Als je de commandoregelopties gebruikt, start de mongod instantie dan met de volgende opties:

  • –keyFile ingesteld op het pad van het sleutelbestand, en
  • –replSet ingesteld op de naam van de replicaset.
mongod --keyFile <path-to-keyfile> --replSet <replicaSetName> --bind_ip localhost,<hostname(s)|ip address(es)>

Je kunt extra opties toevoegen als dat nodig is voor je configuratie. Als je bijvoorbeeld wilt dat externe clients verbinding maken met je deployment of dat je ideploymentmembers op verschillende hosts draaien, geef dan de –bind_ip op. Zie voor meer informatie Localhost Binding Compatibility Changes.

Maak vervolgens verbinding met een member van de replicaset via de localhost interface. Je moet mongosh draaien op dezelfde fysieke machine als de mongod instantie. Deze interface is alleen beschikbaar als er geen gebruikers zijn aangemaakt voor de deployment en sluit automatisch na het aanmaken van de eerste gebruiker.

Vervolgens starten we de replicaset op. Voer vanuit mongosh de methode rs.initiate() uit:

rs.initiate(
  {
    _id: "myReplSet",
    members: [
      { _id: 0, host: "mongo1:27017" },
      { _id: 1, host: "mongo2:27017" },
      { _id: 2, host: "mongo3:27017" }
    ]
  }
)

Zoals eerder besproken kiest deze methode een van de members als primair member van de replicaset. Gebruik rs.status() om het primaire member te vinden. Maak verbinding met het primaire member voordat je verder gaat.

Maak nu de gebruikersbeheerder aan. Je kunt een gebruiker toevoegen met de methode db.createUser(). Zorg ervoor dat de gebruiker minstens de rol userAdminAnyDatabase moet hebben in de admindatabase.

Het volgende voorbeeld maakt de gebruiker ‘batman’ aan met de rol userAdminAnyDatabase op de admin database:

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "batman",
    pwd: passwordPrompt(), // or cleartext password
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

Voer het eerder aangemaakte wachtwoord in als daarom wordt gevraagd.

Vervolgens moet je je authentiseren als de gebruikersbeheerder. Gebruik hiervoor db.auth() om je te authentiseren. Bijvoorbeeld:

db.getSiblingDB(“admin”).auth(“batman”, passwordPrompt()) // of cleartext wachtwoord

Als alternatief kun je een nieuwe mongosh instantie verbinden met het primaire replicaset member met behulp van de parameters -u <username>, -p <password>, en de --authenticationDatabase.

mongosh -u "batman" -p  --authenticationDatabase "admin"

Zelfs als je het wachtwoord niet opgeeft in het -p commandoregelveld, vraagt mongosh om het wachtwoord.

Maak tenslotte de clusterbeheerder aan. De rol clusterAdmin geeft toegang tot replicatiebewerkingen, zoals het configureren van de replicaset.

Laten we een clusterbeheerder gebruiker aanmaken en de rol clusterAdmin toewijzen in de admindatabase:

db.getSiblingDB("admin").createUser(
  {
    "user": "robin",
    "pwd": passwordPrompt(),     // or cleartext password
    roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  }
)

Voer het wachtwoord in als daarom wordt gevraagd.

Als je wilt, kun je extra gebruikers aanmaken om clients toe te staan en interactie te hebben met de replicaset.

En voila! Je hebt met succes keyfile authenticatie ingeschakeld!

Samenvatting

Replicatie is een essentiële vereiste als het gaat om databases, vooral naarmate meer bedrijven opschalen. Het verbetert op grote schaal de prestaties, gegevensbeveiliging en beschikbaarheid van het systeem. Over prestaties gesproken, het is cruciaal voor je WordPress database om prestatieproblemen te monitoren en te verhelpen, bijvoorbeeld met Kinsta APM, Jetpack en Freshping om er een paar te noemen.

Replicatie helpt de gegevensbescherming via meerdere servers te waarborgen en voorkomt dat je servers last krijgen van zware downtime (of nog erger – je gegevens helemaal kwijtraken). In dit artikel behandelden we het maken van een replicaset en enkele tips voor troubleshooting, samen met het belang van replicatie. Gebruik je MongoDB replicatie voor je bedrijf en is het van pas gekomen? Laat het ons weten in de commentsectie hieronder!

Jeremy Holcombe Kinsta

Content & Marketing Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems ;).