MongoDB är en NoSQL-databas som använder JSON-liknande dokument med dynamiska scheman. När du arbetar med databaser så är det alltid bra att ha en beredskapsplan om en av dina databasservrar skulle gå sönder. Du bör därför minska risken för att något sådant ska hända genom att utnyttja ett smart hanteringsverktyg för din WordPress-webbplats.

Det är med andra ord bra att ha många kopior av dina data. Detta minskar även läsfördröjningarna. Samtidigt så kan det förbättra databasens skalbarhet och tillgänglighet. Det är här som replikering kommer in i bilden. Replikering definieras som en praxis där man synkroniserar data mellan flera databaser.

I den här artikeln så kommer vi att dyka ner i de olika framträdande aspekterna av MongoDB-replikering, som exempelvis dess funktioner och mekanismer.

Vad är replikering i MongoDB?

I MongoDB så utför replika-uppsättningar en replikering. Detta är en grupp servrar som upprätthåller samma datamängd genom replikering. Du kan även använda MongoDB-replikering som en del av belastningsutjämning. Här kan du fördela skriv- och läsoperationer över alla instanser, baserat på användningsområdet.

Vad är en MongoDB-replikauppsättning?

En MongoDB-instans som ingår i en viss replika-uppsättning är en medlem. Varje replika-uppsättning måste ha en primär medlem och minst en sekundär medlem.

Den primära medlemmen är den primära åtkomstpunkten för transaktioner med replika-uppsättningen. Det är även den enda medlemmen som kan acceptera skrivoperationer. Replikering kopierar först den primära medlemmens oplog (operationslogg). Därefter så upprepar den de loggade ändringarna på sekundärernas respektive datamängder. Som ett resultat så kan varje replika-uppsättning endast ha en primär medlem åt gången. Om flera primära enheter tar emot skrivoperationer så kan detta exempelvis leda till datakonflikter.

Vanligtvis så frågar applikationen endast efter den primära medlemmen för skriv- och läsoperationer. Du kan utforma din installation så att den läser från en eller flera av de sekundära medlemmarna. Asynkron dataöverföring kan leda till att sekundära noders läsningar serverar gamla data. Som ett resultat så är ett sådant arrangemang inte idealiskt för alla användningsområden.

Funktioner för replika-uppsättningar

Mekanismen för automatisk failover skiljer MongoDB: s replika-uppsättningar från konkurrenterna. I avsaknad av en primär så väljer en automatiserad omröstning bland de sekundära noderna en ny primär.

MongoDB Replika-uppsättning vs MongoDB-kluster

En MongoDB replika-uppsättning skapar olika kopior av samma datamängd i replika-uppsättningsnoderna. Det primära syftet med en replika-uppsättning är att:

  • Erbjuda en inbyggd säkerhetskopieringslösning
  • Öka tillgängligheten av data

Ett MongoDB-kluster är en helt annan sak. Det distribuerar data över många noder med hjälp av en shardnyckel. Denna process fragmenterar data i många delar som kallas shards. Därefter så kopieras varje shard till en annan nod. Ett kluster syftar till att stödja stora datamängder och verksamhet med hög genomströmning. Detta uppnås genom att arbetsbelastningen skalas horisontellt.

Här är skillnaden mellan en replika-uppsättning och ett kluster, i lekmannatermer:

  • Ett kluster fördelar arbetsbelastningen. Det lagrar även datafragment (shards) på många servrar.
  • En replika-uppsättning duplicerar datamängden helt och hållet.

MongoDB gör det möjligt att kombinera dessa funktioner genom att skapa ett sharded kluster. Här kan du replikera varje shard till en sekundär server. Som ett resultat så kan en shard erbjuda en hög redundans och datatillgänglighet.

Att underhålla och konfigurera en replika-uppsättning kan vara tekniskt påfrestande och tidskrävande. Och att hitta rätt hosting-leverantör? Det är en helt annan huvudvärk. Med så många alternativ där ute så är det lätt att slösa bort timmar på att göra efterforskning i stället för att bygga upp ditt företag.

Låt mig ge dig en kort information om ett verktyg som gör allt detta och mycket mer, så att du kan återgå till att jobba med din tjänst/produkt.

Kinsta’s lösning för applikationshosting är betrodd av över 55 000 utvecklare. Du kan komma igång med den med endast 3 enkla steg. Om detta låter för bra för att vara sant så finns här några fler fördelar med att använda Kinsta:

  • Njut av bättre prestanda med Kinsta’s interna anslutningar: Glöm dina problem med delade databaser. Byt till dedikerade databaser med interna anslutningar. Som ett resultat så slipper du begränsningar i fråga om antalet sökfrågor eller antal rader. Kinsta är snabbare, säkrare och kommer inte att fakturera dig för intern bandbredd/trafik.
  • En funktionsuppsättning som är skräddarsydd för utvecklare: Skala din applikation på den robusta plattformen som stöder Gmail, YouTube och Google Search. Du kan vara säker på att du är i trygga händer.
  • Njut av oöverträffade hastigheter med ett datacenter som du själv väljer: Välj den region som fungerar bäst för dig och dina kunder. Med över 25 datacenter att välja mellan så har Kinsta 260+ PoP: s som garanterar en maximal hastighet och en global närvaro för din webbplats.

Prova Kinsta’s lösning för applikationshosting kostnadsfritt idag!

Hur fungerar replikering i MongoDB?

I MongoDB så skickar du skrivoperationer till den primära servern (noden). Den primära servern tilldelar operationerna över sekundära servrar och replikerar data.

Illustration av MongoDB's replikeringsprocess (Bildkälla: MongoDB)
Illustration av MongoDB’s replikeringsprocess (Bildkälla: MongoDB)

Tre typer av MongoDB-noder

Av de tre typerna av MongoDB-noder så har två dykt upp tidigare: primära och sekundära noder. Den tredje typen av MongoDB-noder som är användbar vid replikering är en arbiter. Arbiter-noden har ingen kopia av datamängden och kan inte bli en primär nod. Med detta sagt så deltar arbiter-noden i valen av primärnod.

Vi har tidigare nämnt vad som händer när den primära noden går ner, men vad händer om detta händer för de sekundära noderna? I det scenariot så blir den primära noden sekundär och databasen blir oåtkomlig.

Val av medlem

Valet kan ske i följande scenarier:

  • Initialisering av en replika-uppsättning
  • Förlust av anslutning till den primära noden (som kan upptäckas med hjälp av heartbeat)
  • Underhåll av en replika-uppsättning med hjälp av metoderna rs.reconfig eller stepDown
  • Lägg till en ny nod till en befintlig replika-uppsättning

En replika-uppsättning kan ha upp till 50 medlemmar, men endast 7 eller färre kan rösta i ett val.

Den genomsnittliga tiden innan ett kluster väljer en ny primär nod bör inte överstiga 12 sekunder. Val-algoritmen kommer att försöka att ha den sekundära med den högsta prioriteringen tillgänglig. Samtidigt så kan medlemmarna med prioritetsvärdet 0 inte bli primära och deltar inte i valet.

Sekundär nod som blir primär (Bildkälla: Medium)
Sekundär nod som blir primär (Bildkälla: Medium)

Write Concern

För hållbarhetens skull så har skriv-operationer en ram för att kopiera data i ett visst antal noder. Du kan till och med erbjuda feedback till klienten med detta. Det här ramverket är även känt som ”write concern”. Det har datavärdiga medlemmar som måste bekräfta ett skrivintresse innan operationen returneras som lyckad. Generellt så har replika-uppsättningarna värdet 1 som ett skrivproblem. Som ett resultat så är det bara den primära som ska bekräfta skrivningen innan den returnerar bekräftelsen för skriv-begärandet.

Du kan även öka antalet medlemmar som behöver bekräfta skriv-operationen. Det finns inget tak för hur många medlemmar som du kan ha. Men om antalet är högt så måste du hantera en hög latenstid. Detta beror på att klienten måste vänta på bekräftelse från alla medlemmar. Du kan även ställa in skriv-begärandet för ”majoriteten”.” Detta beräknar mer än hälften av medlemmarna efter att de har fått sin bekräftelse.

Läspreferens

För läshändelser så kan du ange läspreferensen. Den beskriver hur databasen styr begärandet till medlemmarna i replika-uppsättningen. Det är generellt endast den primära noden som tar emot läshanteringen, men klienten kan ange en läspreferens för att skicka läshanteringen till sekundära noder. Här är alternativen för läspreferensen:

  • primaryPreferred: Om den primära noden inte är tillgänglig så hämtas data från de sekundära noderna.
  • primary: Alla läshändelser kommer från den primära noden.
  • secondary: Alla läshändelser utförs av de sekundära noderna.
  • Closest: Här dirigeras läs-begärandena till den närmast nåbara noden, som kan upptäckas genom att köra kommandot ping. Resultatet av läshändelserna kan komma från vilken medlem som helst i replika-uppsättningen, oavsett om det är den primära eller den sekundära.
  • secondaryPreferred: Här kommer de flesta läsoperationer från de sekundära noderna. Om ingen av dem är tillgänglig så hämtas uppgifterna dock från den primära noden.

Synkronisering av data i replika-uppsättningar

För att upprätthålla uppdaterade kopior av den delade datamängden så replikerar eller synkroniserar sekundära medlemmar i en replika-uppsättning data från andra medlemmar.

MongoDB utnyttjar två former av datasynkronisering. Dels initial synkronisering för att fylla nya medlemmar med hela datamängden. Det nyttjas även en replikering för att utföra löpande ändringar i den fullständiga datamängden.

Initial synkronisering

Under den initiala synkroniseringen så kör en sekundär nod kommandot init sync . Som ett resultat så synkroniseras alla data från den primära noden till en annan sekundär nod som innehåller de senaste uppgifterna. Den sekundära noden utnyttjar därför konsekvent funktionen tailable cursor . Detta görs för att fråga efter de senaste oplog-posterna i samlingen local.oplog.rs i den primära noden. Sedan tillämpas dessa operationer i dessa oplog-poster.

Från MongoDB 5.2 så kan inledande synkroniseringar vara filkopieringsbaserade eller logiska.

Logisk synkronisering

När du utför en logisk synkronisering så utför MongoDB:

  1. Utveckling av alla samlingsindex när dokumenten kopieras för varje samling.
  2. Duplikering av alla databaser utom den lokala databasen. mongod skannar varje samling i alla källdatabaser och lägger in alla data i sina dubbletter av dessa samlingar.
  3. Utförande av alla ändringar i datamängden. Genom att utnyttja op-loggen från källan så uppgraderar mongod sin datamängd för att beskriva replika-uppsättningens aktuella tillstånd.
  4. Extrahering av nytillkomna oplog-poster under datakopieringen. MongoDB ser till att målmedlemmen har tillräckligt med diskutrymme i den lokala databasen för att preliminärt lagra dessa oplog-poster under hela datakopieringsfasen.

När den första synkroniseringen är klar så övergår medlemmen från STARTUP2 till SECONDARY .

Initial synkronisering baserad på filkopiering

Du kan endast utföra detta om du använder MongoDB Enterprise. Den här processen kör den första synkroniseringen genom att duplicera och flytta filerna i filsystemet. Denna synkroniseringsmetod kan i vissa fall vara snabbare än logisk initial synkronisering. Tänk på att en filkopieringsbaserad initial synkronisering kan leda till felaktiga beräkningar om du kör count()-metoden utan ett frågepredikat.

Men den här metoden har även sina begränsningar:

  • Under en filkopieringsbaserad inledande synkronisering så kan du inte skriva till den lokala databasen för den medlem som synkroniseras. Som ett resultat så kan du inte heller köra en säkerhetskopiering av den medlem som synkroniseras till eller den medlem som synkroniseras ifrån.
  • När MongoDB utnyttjar den krypterade lagringsmotorn så används källnyckeln för att kryptera destinationen.
  • Du kan endast köra en första synkronisering från en given medlem åt gången.

Replikering

Sekundära medlemmar replikerar data konsekvent efter den första synkroniseringen. De duplicerar op-loggningen från deras synkronisering från källan och utför dessa operationer i en asynkron process.

Dessa medlemmar kan automatiskt ändra sin synkronisering från källan vid behov på grundval av förändringar i ping-tiden och tillståndet för andra medlemmars replikering.

Strömmad replikering

Från och med MongoDB 4.4 så skickar synkronisering från källor en kontinuerlig ström av oplog-poster till deras synkroniserande sekundärer. Strömmad replikering minskar replikerings-fördröjningen i nätverk med hög belastning och hög latens. Som ett resultat av denna replikering så gäller även detta:

  • Risken minskas för att förlora skrivoperationer med w:1 på grund av primärt felbyte.
  • Stelheten minskas vid läsning från sekundära replikor.
  • Väntetiden minskas för skrivoperationer med w:“majority” och w:>1. Kort sagt, alla skrivproblem som behöver vänta på replikering.
Replikering med flera trådar

MongoDB skriver operationer i omgångar genom flera trådar för att förbättra samtidigheten. Det grupperar partierna efter dokument-ID och tillämpar varje grupp av operationer med en annan tråd.

MongoDB utför alltid skrivoperationer på ett givet dokument i dess ursprungliga skrivordning. Detta ändrades i MongoDB 4.0.

Från och med MongoDB 4.0 så har läshändelser som är riktade mot sekundära dokument och som är konfigurerade med en lässäkerhetsnivå på “majority” eller “local” ändrats. De kommer nu att läsas från en WiredTiger-snapshot av data om läsningen sker på ett sekundärt dokument där replikerings-batcherna tillämpas. Läsning från en ögonblicksbild garanterar en enhetlig bild av data och gör att läsningen sker samtidigt med den pågående replikeringen utan att den behöver låsas.

Som ett resultat så behöver sekundärläsningar som kräver dessa lässäkerhetsnivåer inte längre vänta på att replikerings-batcher ska tillämpas utan kan hanteras när de tas emot.

Så här skapar du en MongoDB replika-uppsättning

Som vi nämnde tidigare så hanterar MongoDB replikering genom replika-uppsättningar. Under de kommande avsnitten så kommer vi att belysa några metoder som du kan använda för att skapa replikauppsättningar för ditt användningsområde.

Metod 1: Skapa en ny MongoDB replika-uppsättning på Ubuntu

Innan vi börjar så måste du se till att du har minst tre servrar som kör Ubuntu 20.04, med MongoDB installerat på varje server.

För att skapa en replika-uppsättning så är det viktigt att ange en adress där varje medlem av replika-uppsättningen kan nås av andra i uppsättningen. I det här fallet så har vi tre medlemmar i uppsättningen. Vi kan använda IP-adresser, men detta rekommenderas inte eftersom adresserna kan ändras oväntat. Ett bättre alternativ kan vara att använda de logiska DNS-hostnamnen när man konfigurerar replika-uppsättningar.

Vi kan göra detta genom att konfigurera underdomänen för varje replika-medlem. Även om detta kan vara idealiskt för en produktionsmiljö så kommer det här avsnittet att beskriva hur man konfigurerar DNS-upplösning genom att redigera varje servers respektive hosts-fil. Med denna fil så kan vi tilldela läsbara hostnamn till numeriska IP-adresser. Om din IP-adress ändras så är det enda som du behöver göra att uppdatera hosts-filerna på de tre servrarna. Som ett resultat så slipper du konfigurera om replika-uppsättningen från grunden!

För det mesta så lagras hosts i katalogen /etc/. Upprepa nedanstående kommandon för var och en av dina tre servrar:

sudo nano /etc/hosts

I kommandot ovan så använder vi nano som textredigerare, men du kan använda vilken textredigerare som du vill. Efter de första raderna som konfigurerar localhost så lägger du till en post för varje medlem i replika-uppsättningen. Dessa poster har formen av en IP-adress följt av ett människoläsbart namn som du väljer. Du kan kalla dem vad du vill, men se till att de är beskrivande så att du kan skilja mellan varje medlem. I den här handledningen så kommer vi att använda nedanstående hostnamn:

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

Med dessa hostnamn så skulle dina /etc/hosts-filer se ut som följande markerade rader:

Illustration av hostnamn
Illustration av hostnamn

Spara och stäng filen.

Efter att ha konfigurerat DNS-upplösningen för replika-uppsättningen så måste vi uppdatera brandväggsreglerna så att de kan kommunicera med varandra. Kör följande ufw-kommando på mongo0 för att ge mongo1 tillgång till port 27017 på mongo0:

sudo ufw allow from mongo1_server_ip to any port 27017

I stället för parametern mongo1_server_ip så anger du mongo1-serverns faktiska IP-adress. Har du uppdaterat Mongo-instansen på den här servern så att den använder en annan port än standardporten? Se då till att ändra 27017 så att den motsvarar den port som din MongoDB-instans använder.

Lägg nu till ytterligare en brandväggsregel för att ge mongo2 tillgång till samma port:

sudo ufw allow from mongo2_server_ip to any port 27017

Ange mongo2-serverns faktiska IP-adress i stället för parametern mongo2_server_ip. Uppdatera sedan brandväggsreglerna för dina två andra servrar. Kör följande kommandon på mongo1-servern och se till att ändra IP-adresserna i stället för parametern server_ip. Som ett resultat så motsvarar de mongo0’s respektive mongo2’s IP-adresser:

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

Kör slutligen dessa två kommandon på mongo2. Se återigen till att du anger rätt IP-adresser för varje server:

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

Nästa steg är att uppdatera konfigurationsfilen för varje MongoDB-instans så att externa anslutningar tillåts. För att tillåta detta så måste du ändra konfigurationsfilen på varje server så att IP-adressen och replika-uppsättningen anges. Även om du kan använda vilken textredigerare som du vill, så använder vi återigen textredigeraren nano. Låt oss göra följande ändringar i varje mongod.conf-fil.

På mongo0:

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

På mongo1:

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

På mongo2:

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

Med detta så har du aktiverat replikering för varje servers MongoDB-instans.

Du kan nu initiera replika-uppsättningen genom att använda metoden rs.initiate(). Den här metoden behöver bara utföras på en enda MongoDB-instans i replika-uppsättningen. Kontrollera att replika-uppsättningens namn och medlem överensstämmer med de konfigurationer som du gjorde i varje konfigurationsfil tidigare.

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

Om metoden returnerar ”ok”: 1 i resultatet så betyder detta att replika-uppsättningen startades korrekt. Nedan så finns ett exempel på hur utmatningen bör se ut:

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

Stäng av MongoDB-servern

Du kan stänga av en MongoDB-server genom att använda metoden db.shutdownServer(). Nedan så följer syntaxen för samma metod. Både force och timeoutsecs är valfria parametrar.

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

Den här metoden kan misslyckas om medlemmen i mongod replika-uppsättningen exempelvis kör vissa operationer som index-uppbyggnad. För att avbryta operationerna och tvinga medlemmen att stänga ner så kan du ange den booleska parametern force till true.

Starta om MongoDB med –replSet

För att återställa konfigurationen så ser du till att alla noder i din replika-uppsättning är stoppade. Ta sedan bort den lokala databasen för varje nod. Starta den igen med flaggan –replSet och kör rs.initiate() på endast en mongodinstans för replika-uppsättningen.

mongod --replSet "rs0"

rs.initiate() kan ta med ett valfritt konfigurationsdokument för replika-uppsättningen, nämligen:

  • Alternativet Replication.replSetName eller —replSet för att ange namnet på replika-uppsättningen i fältet _id.
  • Matrisen members, som innehåller ett dokument för varje medlem i replika-uppsättningen.

Metoden rs.initiate() utlöser ett val och väljer en av medlemmarna som primär medlem.

Lägg till medlemmar i replika-uppsättningen

För att lägga till medlemmar i uppsättningen så startar du mongod-instanser på olika maskiner. Starta sedan en mongoklient och använd kommandot rs.add().

Kommandot rs.add() har följande grundläggande syntax:

rs.add(HOST_NAME:PORT)

Exempelvis,

Anta att mongo1 är din mongod-instans och att den lyssnar på port 27017. Använd kommandot rs.add() för att lägga till den här instansen i replika-uppsättningen.

rs.add("mongo1:27017")

Det är först när du är ansluten till den primära noden som du kan lägga till en mongo-instans i replika-uppsättningen. För att kontrollera om du är ansluten till den primära enheten så använder du kommandot db.isMaster().

Ta bort användare

För att ta bort en medlem så kan vi använda rs.remove()

För att göra detta så stänger du först av den mongod-instans som du vill ta bort med hjälp av metoden db.shutdownServer() som vi diskuterade ovan.

Därefter så ansluter du till replika-uppsättningens nuvarande primära enhet. För att fastställa den aktuella primära enheten så använder du db.hello() när du är ansluten till en medlem i replika-uppsättningen. När du har fastställt den primära replikan så kör du något av följande kommandon:

rs.remove("mongodb-node-04:27017")
rs.remove("mongodb-node-04")
Bilden ovan visar att noden har tagits bort från replika-uppsättningen. (Bildkälla: Bmc)
Bilden ovan visar att noden har tagits bort från replika-uppsättningen. (Bildkälla: Bmc)

Om replika-uppsättningen behöver välja en ny primär nod så kan MongoDB koppla bort skalet kortvarigt. I det här scenariot så kommer den automatiskt att återanslutas en gång till. Det kan även visa felmeddelandet DBClientCursor::init call() om kommandot lyckas.

Metod 2: Konfigurera en MongoDB-replika-uppsättning för distribuering och testning

Du kan generellt konfigurera replika-uppsättning för testning med RBAC aktiverat eller inaktiverat. I den här metoden så kommer vi att konfigurera replika-uppsättningen med åtkomstkontrollen inaktiverad för att distribuera det i en testmiljö.

Först så skapar du kataloger för alla instanser som ingår i replika-uppsättningen med följande kommando:

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

Det här kommandot kommer att skapa kataloger för tre MongoDB-instanser replicaset0-0, replicaset0-1 och replicaset0-2. Starta nu MongoDB-instanserna för var och en av dem med hjälp av följande kommandon:

För server 1:

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

För Server 2:

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

För server 3:

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

Parametern –oplogSize används för att förhindra att maskinen överbelastas under testfasen. Den bidrar till att minska mängden diskutrymme som varje disk tar i anspråk.

Anslut nu till en av instanserna med hjälp av Mongo-skalet genom att ansluta med portnumret nedan.

mongo --port 27017

Vi kan använda kommandot rs.initiate() för att starta replikeringsprocessen. Du måste ersätta parametern hostname med ditt systems namn.

rs conf = {

  _id: "replicaset0",

  members: [

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

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

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

   ] }

Du kan nu skicka konfigurationsobjektfilen som parameter för initiate-kommandot och använda det på följande sätt:

rs.initiate(rsconf)

Sen är du klar! Du har framgångsrikt skapat en MongoDB replika-uppsättning för utvecklings– och teständamål.

Metod 3: Omvandla en fristående instans till en MongoDB replika-uppsättning

MongoDB tillåter sina användare att omvandla sina fristående instanser till replika-uppsättningar. Medan fristående instanser oftast används för test- och utvecklingsfasen så är replika-uppsättningar en del av produktionsmiljön.

För att komma igång så stänger vi av vår mongod-instans med följande kommando:

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

Starta om din instans genom att använda parametern –repelSet i kommandot för att ange den replika-uppsättning som du ska använda:

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

Du måste ange namnet på din server tillsammans med den unika adressen i kommandot.

Anslut skalet till din MongoDB-instans och använd initiate-kommandot för att starta replikeringsprocessen och konvertera instansen till en replika-uppsättning. Du kan utföra alla grundläggande operationer som att lägga till eller ta bort en instans med hjälp av följande kommandon:

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

Dessutom så kan du kontrollera statusen för MongoDB-replikerna med hjälp av kommandona rs.status() och rs.conf().

Metod 4: MongoDB Atlas – ett enklare alternativ

Replikering och sharding kan jobba ihop för att bilda något som kallas ett sharded kluster. Även om installation och konfiguration kan vara ganska tidskrävande, så är MongoDB Atlas ett bättre alternativ än de metoder som har nämnts tidigare.

Det automatiserar dina replika-uppsättningar. Som ett resultat så blir processen enkel att genomföra. Det kan distribuera globalt sharded replika-uppsättningar med några få klick, vilket exempelvis möjliggör katastrofåterställning, enklare hantering, datalokalisering och multiregionala distribueringar.

I MongoDB Atlas så måste vi skapa kluster – de kan antingen vara en replika-uppsättning eller ett sharded-kluster. För ett visst projekt så är antalet noder i nån annan regions kluster begränsat till totalt 40.

Detta utesluter kostnadsfria eller delade kluster och Google molnregioner som kommunicerar med varandra. Det totala antalet noder mellan två regioner måste uppfylla denna begränsning. Det kanske exempelvis finns ett projekt där:

  • Region A har 15 noder.
  • Medan Region B har 25 noder
  • Slutligen så har Region C 10 noder

Vi kan endast tilldela ytterligare 5 noder till region C eftersom,

  1. Region A + Region B = 40, vilket uppfyller begränsningen att 40 är det högsta tillåtna antalet noder.
  2. Region B + Region C = 25+10+5 (ytterligare noder som tilldelas C) = 40; uppfyller begränsningen att 40 är det högsta tillåtna antalet noder.
  3. Region A + Region C = 15+10+5 (ytterligare noder tilldelas C) = 30; uppfyller begränsningen att 40 är det högsta tillåtna antalet noder.

Om vi tilldelar ytterligare 10 noder till region C, så att region C får 20 noder, så blir region B + region C = 45 noder. Detta skulle överskrida den givna begränsningen, så du kanske inte kan skapa ett kluster med flera regioner.

När du skapar ett kluster så skapar Atlas en nätverks-container i projektet för molnleverantören om den inte fanns där tidigare. Om du vill skapa ett kluster med replikat-uppsättning i MongoDB Atlas så kör du följande kommando i Atlas CLI:

atlas clusters create [name] [options]

Se till att du anger ett beskrivande klusternamn, eftersom detta inte kan ändras efter att klustret har skapats. Argumentet kan innehålla ASCII-bokstäver, siffror och bindestreck.

Det finns flera alternativ tillgängliga för klusterskapande i MongoDB baserat på dina krav. Om du exempelvis vill ha kontinuerlig moln-säkerhetskopiering för ditt kluster så ställer du in --backup till true.

Hantering av replikerings-fördröjning

Replikerings-fördröjning kan vara ganska avskräckande. Det är en fördröjning mellan en operation på den primära och tillämpningen av denna operation från oplog till den sekundära. Om din verksamhet hanterar stora datamängder så förväntas det uppstå en fördröjning inom ett visst tröskelvärde. Ibland så kan dock externa faktorer även bidra till och öka fördröjningen.

  1. Du dirigerar din nätverkstrafik med en stabil och tillräckligt stor bandbredd. Nätverkets latens spelar en stor roll när det gäller att påverka din replikering. Om nätverket inte räcker till för att tillgodose replikerings-processens behov så kommer det att uppstå fördröjningar i replikeringen av data i hela replika-uppsättningen.
  2. Du har tillräckligt stor disk-genomströmning. Om filsystemet och diskenheten på den sekundära enheten inte kan spola data till disken lika snabbt som den primära, så kommer den sekundära enheten att ha svårt att hänga med. Som ett resultat så behandlar de sekundära noderna skriv-begärandena långsammare än den primära noden. Detta är ett vanligt problem i de flesta system med flera medlemmar, inklusive virtualiserade instanser och storskaliga installationer.
  3. Du begär en skrivbekräftelse efter ett intervall för att ge de sekundära noderna möjlighet att komma ikapp den primära. Detta gäller särskilt när du vill utföra en massladdnings-operation eller datainmatning som kräver ett stort antal skrivningar till den primära noden. De sekundära enheterna kommer inte att kunna läsa op-loggen tillräckligt snabbt för att hålla jämna steg med ändringarna, särskilt inte med okvitterade skriv-begäranden.
  4. Du identifierar de pågående bakgrundsuppgifterna. Vissa uppgifter som cronjobb, serveruppdateringar och säkerhetskontroller kan ha oväntade effekter på nätverket eller diskanvändningen. Som ett resultat så kan det bli förseningar i replikerings-processen.

Om du är osäker på om det finns en replikerings-fördröjning i din applikation, oroa dig inte – i nästa avsnitt så diskuterar vi strategier för felsökning!

Felsökning av MongoDB-replika-uppsättningar

Du har lyckats konfigurera dina replika-uppsättningar, men märker att dina data är inkonsekventa mellan servrarna. Detta är starkt alarmerande för storskaliga företag. Med snabba felsökningsmetoder så kan du dock hitta orsaken eller till och med rätta till problemet! Nedan så finns några vanliga strategier för felsökning av replika-uppsättningar som kan vara till nytta:

Kontrollera replika-status

Vi kan kontrollera replika-uppsättningens aktuella status och statusen för varje medlem genom att köra följande kommando i en mongosh-session som är ansluten till replika-uppsättningens primära.

 rs.status()

Kontrollera replika-fördröjningen

Som vi har diskuterat tidigare så kan replikerings-fördröjning vara ett allvarligt problem. Som ett resultat av detta så kan nämligen ”försenade” medlemmar inte bli primära så snabbt och risken ökar för att distribuerade läshändelser blir inkonsekventa. Vi kan kontrollera replika-loggens aktuella längd genom att använda följande kommando:

rs.printSecondaryReplicationInfo()

Detta returnerar värdet syncedTo som är den tid då den senaste oplog-posten skrevs till den sekundära för varje medlem. Här är ett exempel för att visa samma sak:

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

En fördröjd medlem kan visas som 0 sekunder efter den primära när inaktivitetsperioden på den primära är större än värdet members[n].secondaryDelaySecs.

Testa anslutningar mellan alla medlemmar

Varje medlem i en replika-uppsättning måste kunna ansluta till alla andra medlemmar. Se alltid till att verifiera anslutningarna i båda riktningarna. Oftast så förhindrar brandväggskonfigurationer eller nätverks-topologier normala och nödvändiga anslutningar. Som ett resultat så kan replikering blockeras.

Låt oss exempelvis anta att mongod-instansen binder till både localhost och hostname ”ExampleHostname” som är associerad med IP-adressen 198.41.110.1:

mongod --bind_ip localhost, ExampleHostname

För att ansluta till den här instansen så måste fjärrklienterna ange hostnamnet eller IP-adressen:

mongosh --host ExampleHostname
mongosh --host 198.41.110.1

Om en replika-uppsättning består av tre medlemmar, m1, m2 och m3, som använder standardporten 27017, så ska du testa anslutningen enligt nedan:

På m1:

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

På m2:

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

På m3:

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

Om någon anslutning i någon riktning misslyckas så måste du kontrollera din brandväggskonfiguration och konfigurera om den så att anslutningarna tillåts.

Säker kommunikation med nyckelfils-autentisering

Som standard så bygger nyckelfils-autentisering i MongoDB på autentiserings-mekanismen SCRAM (salted challenge response authentication mechanism). För att göra detta så måste MongoDB läsa och validera användarens angivna autentiserings-uppgifter som innehåller en kombination av användarnamn, lösenord och autentiserings-databas. Detta är information som den specifika MongoDB-instansen känner till. Exakt denna mekanism används för att autentisera användare som anger ett lösenord när de ansluter till databasen.

När du aktiverar autentisering i MongoDB så aktiveras RBAC (Role-Based Access Control) automatiskt för replika-uppsättningen, och användaren tilldelas en eller flera roller som bestämmer deras åtkomst till databasresurser. När RBAC är aktiverat så innebär detta att endast den giltiga autentiserade Mongo-användaren med lämpliga privilegier kan få tillgång till resurserna i systemet.

Nyckelfilen fungerar som ett delat lösenord för varje medlem i klustret. Som ett resultat så blir det möjligt för varje Mongod-instans i replika-uppsättningen att använda innehållet i nyckelfilen. Detta gäller exempelvis det delade lösenordet för autentisering av andra medlemmar i distribueringen.

Endast de mongod-instanser som har rätt nyckelfil kan ansluta sig till replika-uppsättningen. En nyckels längd måste vara mellan 6 och 1024 tecken och får endast innehålla tecken i base64-uppsättningen. Observera att MongoDB tar bort vitrymdstecken vid läsning av nycklar.

Du kan generera en nyckelfil med hjälp av olika metoder. I den här handledningen så använder vi openssl för att generera en komplex sträng med 1024 slumpmässiga tecken som kan användas som ett delat lösenord. Därefter så används chmod för att ändra filbehörigheterna så att endast filägaren får läsbehörighet. Undvik att lagra nyckelfilen på lagringsmedier som lätt kan kopplas bort från den maskinvara som hostar mongod-instanserna. Det kan exempelvis handla om en USB-enhet eller en nätverksansluten lagringsenhet. Nedan så följer kommandot för att generera en nyckelfil:

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

Kopiera sedan nyckelfilen till varje medlem i replika-uppsättningen. Se till att den användare som kör mongod-instanserna är ägare till filen och kan komma åt nyckelfilen. När du har gjort ovanstående så stänger du av alla medlemmar i replika-uppsättningen och börjar med de sekundära. När alla sekundära enheter är offline så kan du gå vidare och stänga av den primära. Det är viktigt att följa den här ordningen för att förhindra eventuella fel. Stäng nu av mongod-instansen genom att köra följande kommando:

use admin
db.shutdownServer()

När kommandot har körts så kommer alla medlemmar i replika-uppsättningen att vara offline. Starta nu om varje medlem i replika-uppsättningen med åtkomstkontrollen aktiverad.

För varje medlem i replika-uppsättningen så startar du mongod-instansen med antingen inställningen i konfigurationsfilen security.keyFile eller kommandoradsalternativet --keyFile.

Om du använder en konfigurationsfil så ställer du in

  • security.keyFile till nyckelfilens sökväg och
  • replication.replSetName till replika-uppsättningens namn.
security:
  keyFile: <path-to-keyfile>
replication:
  replSetName: <replicaSetName>
net:
   bindIp: localhost,<hostname(s)|ip address(es)>

Starta mongod-instansen med hjälp av konfigurationsfilen:

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

Om du använder kommandoradsalternativen så startar du mongod-instansen med följande alternativ:

  • –keyFile är inställd på sökvägen till nyckelfilen, och
  • –replSet är inställd på replika-uppsättningarnas namn.
mongod --keyFile <path-to-keyfile> --replSet <replicaSetName> --bind_ip localhost,<hostname(s)|ip address(es)>

Du kan inkludera ytterligare alternativ som krävs för din konfiguration. Om du exempelvis vill att fjärrklienter ska ansluta till din distribuering eller om dina distribuerings-medlemmar körs på olika hostar, ange –bind_ip. Mer information finns i Ändringar av kompatibiliteten för bindning av localhost.

Anslut sedan till en medlem i replika-uppsättningen via gränssnittet localhost. Du måste köra mongosh på samma fysiska maskin som mongod-instansen. Det här gränssnittet är endast tillgängligt när inga användare har skapats för distribueringen och stängs automatiskt av när den första användaren har skapats.

Därefter så startar vi replika-uppsättningen. Från mongosh så kör du metoden rs.initiate():

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

Som vi diskuterade tidigare så väljer den här metoden en av medlemmarna att vara den primära medlemmen i replika-uppsättningen. För att hitta den primära medlemmen så använder du rs.status(). Anslut till den primära medlemmen innan du fortsätter.

Skapa nu användaren administratör. Du kan lägga till en användare med hjälp av metoden db.createUser(). Se till att användaren åtminstone har rollen userAdminAnyDatabase i administratörs-databasen.

Följande exempel skapar användaren ”batman” med rollen userAdminAnyDatabase i den administrativa databasen:

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

Ange det lösenord som skapades tidigare när du blir tillfrågad.

Därefter så måste du autentisera dig som användaradministratör. Använd db.auth() för att autentisera dig. Exempelvis:

exempel: db.getSiblingDB(”admin”).auth(”batman”, passwordPrompt()) // eller lösenord i klartext

Alternativt så kan du ansluta en ny mongosh-instans till den primära medlemmen i replika-uppsättningen med hjälp av parametrarna -u <username>, -p <password> och --authenticationDatabase.

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

Även om du inte anger lösenordet i kommandoradsfältet -p så frågar mongosh efter lösenordet.

Slutligen så skapar du klusteradministratören. Rollen clusterAdmin ger tillgång till replikeringsåtgärder, exempelvis konfigurering av replika-uppsättningen.

Låt oss skapa en klusteradministratörs-användare och tilldela rollen clusterAdmin i admin-databasen:

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

Ange lösenordet när du blir tillfrågad.

Om du vill så kan du skapa ytterligare användare för att tillåta klienter att interagera med replika-uppsättningen.

Och voila! Du har framgångsrikt aktiverat nyckelfils-autentisering!

Sammanfattning

Replikering har varit ett viktigt krav när det gäller databaser, särskilt i takt med att allt fler företag skalar upp. Det förbättrar systemets prestanda, datasäkerhet och tillgänglighet. Det är helt centralt för din WordPress-databas att övervaka prestandaproblem och åtgärda dem i tid och otid, exempelvis med Kinsta APM, Jetpack och Freshping för att nämna några verktyg.

Replikering hjälper till att säkerställa dataskydd över flera servrar och förhindrar att dina servrar drabbas av tunga driftsstopp (eller ännu värre – att din data går förlorad). I den här artikeln så gick vi igenom skapandet av en replika-uppsättning och några felsökningstips samt vikten av replikering. Använder du MongoDB-replikering i ditt företag och har det visat sig vara användbart för dig? Låt oss veta detta i kommentarsfältet nedan!

Jeremy Holcombe Kinsta

Innehålls- och marknadsföringsredaktör på Kinsta, WordPress webbutvecklare och innehållsskribent. Utöver WordPress tycker jag om stranden, golf och filmer. Jag har även problem med långa människor ;).