Docker erstellt Cluster-MongoDB-Implementierungsschritte

Docker erstellt Cluster-MongoDB-Implementierungsschritte

Vorwort

Aufgrund der Geschäftsanforderungen des Unternehmens planen wir, unseren eigenen MongoDB-Dienst aufzubauen. Da die Cloud-Datenbank von MongoDB sehr teuer ist, verwenden wir die Replikationssatzmethode, um einen Cluster mit drei Servern aufzubauen, einem primären, einem sekundären und einem Arbitrierungsserver.

Grundlegende Konzepte

Replikationssatz: Ein Replikationssatz ist ein Cluster von MongoDB-Instanzen, bestehend aus einem Primärserver und mehreren Sekundärservern.

  • Master: Der Masterknoten empfängt alle Schreibvorgänge. Der primäre Knoten zeichnet alle an seinem Datensatz vorgenommenen Änderungen in seinem Oplog auf.
  • Sekundär: Kopiert das Oplog des primären Knotens und wendet Operationen auf dessen Datensatz an. Wenn der primäre Knoten nicht verfügbar ist, wird ein qualifizierter sekundärer Knoten als neuer primärer Knoten gewählt.
  • Schiedsrichter: Lastauswahl. Wenn der primäre Knoten nicht verfügbar ist, wird einer der sekundären Knoten als primärer Knoten ausgewählt.

Sharding:

Master-Slave

  • Beim Ausführen von MongoDB 4.0 oder höher wird die folgende Meldung angezeigt: [main] Master/Slave-Replikation wird nicht mehr unterstützt. Dies bedeutet, dass MongoDB 4.0 und höher die Master-Slave-Replikation nicht mehr unterstützen.

1. Umweltvorbereitung

Verwenden Sie das 64-Bit-System CentOS 7.6, um Docker, Docker-Compose und Docker-Swarm zu installieren

2. KeyFile generieren

  • MongoDB verwendet KeyFile-Authentifizierung. Jede MongoDB-Instanz im Replikatsatz verwendet den KeyFile-Inhalt als gemeinsames Kennwort, um andere Mitglieder zu authentifizieren. Eine MongoDB-Instanz kann einem Replikatsatz nur beitreten, wenn sie über die richtige Schlüsseldatei verfügt.
  • Der Inhalt der Schlüsseldatei muss 6 bis 1024 Zeichen lang sein und der Inhalt der Schlüsseldatei muss für alle Mitglieder des Replikatsatzes gleich sein.
  • Zu beachten ist, dass KeyFile in UNIX-Systemen weder über Gruppenberechtigungen noch über Vollberechtigungen verfügen darf (d. h., die Berechtigungen müssen auf X00 gesetzt sein). Unter Windows werden die Schlüsseldateiberechtigungen nicht überprüft.
  • Sie können zum Generieren der Schlüsseldatei eine beliebige Methode verwenden. Beispielsweise verwendet der folgende Vorgang OpenSSL, um eine komplexe, zufällige Zeichenfolge mit 1024 Zeichen zu generieren. Verwenden Sie dann chmod, um die Dateiberechtigungen so zu ändern, dass nur der Dateibesitzer Leseberechtigung hat.
  • Dies ist die von MongoDB offiziell empfohlene Methode zum Generieren von Schlüsseldateien:
# 400 Berechtigungen sind erforderlich, um die Sicherheit zu gewährleisten, andernfalls meldet Mongod beim Starten von OpenSSL einen Fehler rand -base64 756 > mongodb.key
chmod 400 mongodb.key

2. Erstellen Sie ein hostübergreifendes Netzwerk

Um einen Cluster zu erstellen, müssen wir über Hosts hinweg kommunizieren. Um ein Overlay-Netzwerk zu erstellen, müssen wir das Docker Swarm-Tool verwenden. Docker Swarm ist ein integriertes Cluster-Tool für Docker, mit dem wir Dienste einfacher in einem Cluster von Docker-Daemons bereitstellen können.

Da wir Docker zum Cluster hinzufügen möchten, müssen wir zunächst einen Cluster haben. Wir können den Cluster über Docker Swarm Init auf jeder Docker-Instanz initialisieren.

$ sudo Docker Swarm-Init

Swarm initialisiert: Der aktuelle Knoten (t4ydh2o5mwp5io2netepcauyl) ist jetzt ein Manager.

Um diesem Schwarm einen Arbeiter hinzuzufügen, führen Sie den folgenden Befehl aus:

  Docker Swarm beitreten --Token SWMTKN-1-4dvxvx4n7magy5zh0g0de0xoues9azekw308jlv6hlvqwpriwy-cb43z26n5jbadk024tx0cqz5r 192.168.1.5:2377

Nachdem der Cluster initialisiert wurde, wird diese Docker-Instanz automatisch zum Cluster-Verwaltungsknoten, und andere Docker-Instanzen können dem Cluster beitreten, indem sie den hier abgedruckten Befehl „Docker Swarm Join“ ausführen.

Die zum Cluster hinzugefügten Knoten sind standardmäßig normale Knoten. Wenn Sie dem Cluster als Verwaltungsknoten beitreten möchten, können Sie den Befehl docker swarm join-token verwenden, um den Beitrittsbefehl des Verwaltungsknotens abzurufen.

$ sudo Docker Swarm Join-Token-Manager
Um diesem Swarm einen Manager hinzuzufügen, führen Sie den folgenden Befehl aus:

  Docker-Schwarm beitreten --Token SWMTKN-1-60am9y6axwot0angn1e5inxrpzrj5d6aa91gx72f8et94wztm1-7lz0dth35wywekjd1qn30jtes 192.168.1.5:2377

Wir verwenden diese Befehle, um einen Docker-Cluster für unsere Serviceentwicklung einzurichten und die Docker der relevanten Entwicklungskollegen zu diesem Cluster hinzuzufügen. Damit schließen wir den ersten Schritt zum Aufbau eines hostübergreifenden Netzwerks ab.

Aufbau eines Cross-Host-Netzwerks

Als Nächstes verwenden wir docker network create um das Overlay-Netzwerk zu erstellen.

$ sudo Docker-Netzwerk erstellen --Treiber-Overlay --Attachable MongoDBs

Beim Erstellen des Overlay-Netzwerks müssen wir die Option --attachable hinzufügen, damit Docker-Container auf verschiedenen Maschinen es normal verwenden können.

Nachdem wir dieses Netzwerk erstellt haben, können wir Docker Network LS auf jeder dem Cluster beigetretenen Docker-Instanz verwenden, um die darunter liegende Netzwerkliste anzuzeigen. Wir werden feststellen, dass diese Netzwerkdefinition mit allen Knoten im Cluster synchronisiert wurde.

$ sudo Docker-Netzwerk ls
NETZWERK-ID-NAME TREIBER-UMFANG
## ......
y89bt74ld9l8 MongoDBs Overlay-Schwarm
## ......

Als Nächstes müssen wir die Docker Compose-Definition so ändern, dass sie das bereits definierte Netzwerk verwendet, anstatt ein neues Netzwerk zu erstellen.

Wir müssen nur die externe Eigenschaft des Netzwerks im Abschnitt „Netzwerkdefinition“ der Docker Compose-Konfigurationsdatei auf „true“ setzen, und Docker Compose verbindet alle Container, die es erstellt und die nicht zu Docker Compose gehören, mit diesem Projekt.

Netzwerke:
 Maschenweite:
  extern: wahr

Durch diese Implementierung platzieren wir den gesamten Dienst in einem Netzwerk, das während der Entwicklung Alias-Mapping verwenden kann. Dadurch wird der langwierige Prozess des Wechselns der Dienst-IPs beim Debuggen verschiedener Funktionen vermieden. Bei dieser Struktur müssen wir lediglich den von uns entwickelten Docker beenden und verschiedenen Clustern beitreten lassen, um sofort zwischen verschiedenen gemeinsamen Debugging-Projekten wechseln zu können.

2. Schreiben Sie eine Docker-Compose-Datei

Master-Knoten

Version: "3"
Leistungen: 
 Master:
  Bild: mongo:4.1
  Containername: Master
  Umfeld:
   MONGO_INITDB_ROOT_USERNAME: root
   MONGO_INITDB_ROOT_PASSWORD: 123456
   TZ: „Asien/Shanghai“
  Bände:
   # Mounten Sie das MongoDB-Datenverzeichnis - "/data/docker/mongodb/data/mongo:/data/db:rw"
   # Schlüsseldatei mounten
   – „/data/docker/mongodb/data/mongodb.key:/data/mongodb.key“
  Häfen:
   - „27018:27017“
  Netzwerke:
   - mongodbs
  Befehl:
   # Passwort --auth
   #Name des Replikationssatzes --replSet testSet 
   --oplogGröße 128
   --keyFile /data/mongodb.key
# Schwarm plattformübergreifende Netzwerke:
 mongodbs:
  extern: wahr

Sekundärknoten

Version: "3"
Leistungen: 
sekundär:
 Bild: mongo:4.1
 Containername: sekundär
 Umfeld:
  MONGO_INITDB_ROOT_USERNAME: root
  MONGO_INITDB_ROOT_PASSWORD: 123456
  TZ: „Asien/Shanghai“
 Bände:
  – „/data/docker/mongodb/data/mongo:/data/db:rw“
  – „/data/docker/mongodb/data/mongodb.key:/data/mongodb.key“
 Häfen:
  - „27018:27017“
 Netzwerke:
  - mongodbs
 Befehl:
  --auth
  --replSet Testsatz 
  --oplogGröße 128
  --keyFile /data/mongodb.key
Netzwerke:
mongodbs:
 extern: wahr

Arbitrierungsknoten müssen keine Daten speichern. Sie werden nur verwendet, um einen neuen Masterknoten auszuwählen, wenn der Masterknoten ausfällt. Daher erfordern sie keine Passwörter oder Port-Mapping-Operationen.

Version: "3"
Leistungen:
Schiedsrichter:
 Bild: mongo:4.1
 Containername: Schiedsrichter
 Neustart: immer
 Bände:
  – „/data/docker/mongodb/data/mongo:/data/db:rw“
  – „/data/docker/mongodb/data/mongo_key:/mongo:rw“
 Netzwerke:
  - mongodbs
 Befehl:
  mongod --replSet testSet --smallfiles --oplogSize 128
Netzwerke:
mongodbs:
 extern: wahr

3. Starten Sie den Container

Als nächstes verwenden wir die Container-Orchestrierung, um Container jeweils auf drei Servern zu starten.

docker-compose up -d

4. Replikatsatz konfigurieren

Geben Sie den Masterknotencontainer ein

Docker Exec -it Master Mongo

In der Mongo-Shell ausführen:

> rs.initiieren()
{
   "info2" : "Keine Konfiguration angegeben. Es wird eine Standardkonfiguration für das Set verwendet.",
   "ich" : "7abd89794aa7:27017",
   "OK" : 1
}

Ausführung fortsetzen:

testSet:SEKUNDÄR> rs.add('sekundär:27017')
{
   "OK" : 1,
   "$clusterTime" : {
       "clusterTime" : Zeitstempel(1599562800, 1),
       "Signatur" : {
           "Hash" : BinData(0,"wrxMUIX/0bEyLgCVoQqdLvH59T0="),
           "Schlüssel-ID" : NumberLong("6870069879538450434")
       }
   },
   "Operationszeit" : Zeitstempel(1599562800, 1)
}

Mit der Ausführung fortfahren, wobei „true“ bedeutet, dass dieser Knoten ein Arbitration-Knoten ist

Testsatz:PRIMARY> rs.add('Schiedsrichter:27017',true)
{
   "OK" : 1,
   "$clusterTime" : {
       "clusterTime" : Zeitstempel(1599562838, 1),
       "Signatur" : {
           "Hash" : BinData(0,"p9ub49lLD8ij8nkxpfu2l/AvRRY="),
           "Schlüssel-ID" : NumberLong("6870069879538450434")
       }
   },
   "Operationszeit" : Zeitstempel(1599562838, 1)
}

Konfiguration anzeigen

testSet:PRIMARY> rs.conf()
{
   "_id" : "Testsatz",
   "Version" : 3,
   "Protokollversion" : NumberLong(1),
   "writeConcernMajorityJournalDefault" : wahr,
   "Mitglieder" : [
       {
           "_id" : 0,
           "Gastgeber": "7abd89794aa7:27017",
           "arbiterOnly" : falsch,
           "buildIndexes" : wahr,
           "versteckt" : falsch,
           "Priorität" : 1,
           "Tags" : {

           },
           "SlaveDelay" : ZahlLang(0),
           "Stimmen" : 1
       },
       {
           "_id" : 1,
           "Host": "sekundär:27017",
           "arbiterOnly" : falsch,
           "buildIndexes" : wahr,
           "versteckt" : falsch,
           "Priorität" : 1,
           "Tags" : {

           },
           "SlaveDelay" : ZahlLang(0),
           "Stimmen" : 1
       },
       {
           "_id" : 2,
           "Host": "Schiedsrichter:27017",
           "arbiterOnly" : wahr,
           "buildIndexes" : wahr,
           "versteckt" : falsch,
           "Priorität" : 0,
           "Tags" : {

           },
           "SlaveDelay" : ZahlLang(0),
           "Stimmen" : 1
       }
   ],
   "Einstellungen" : {
       "chainingAllowed" : wahr,
       "HerzschlagIntervallMillis" : 2000,
       "Herzschlag-Zeitüberschreitung in Sekunden" : 10,
       "WahlTimeoutMillis" : 10000,
       "catchUpTimeoutMillis" : -1,
       "catchUpTakeoverDelayMillis" : 30000,
       "getLastErrorModes" : {

       },
       "getLastErrorDefaults" : {
           "w" : 1,
           "wtimeout" : 0
       },
       "Replikatssatz-ID": Objekt-ID("5f576426fe90ef2dd8cd2700")
   }
}

Status anzeigen

testSet:PRIMARY> rs.status()
{
   "set": "Testsatz",
   "Datum" : ISODate("2020-09-08T11:45:12.096Z"),
   "meinStatus" : 1,
   "Begriff" : NumberLong(1),
   "syncingTo" : "",
   "syncSourceHost" : "",
   "syncSourceId" : -1,
   "HerzschlagIntervallMillis" : ZahlLang(2000),
   "optimes" : {
       "letzteCommittedOpTime" : {
           "ts" : Zeitstempel(1599565502, 1),
           "t" : ZahlLang(1)
       },
       "lastCommittedWallTime" : ISODate("2020-09-08T11:45:02.775Z"),
       "readConcernMajorityOpTime" : {
           "ts" : Zeitstempel(1599565502, 1),
           "t" : ZahlLang(1)
       },
       "readConcernMajorityWallTime" : ISODate("2020-09-08T11:45:02.775Z"),
       "angewandteBetriebszeit" : {
           "ts" : Zeitstempel(1599565502, 1),
           "t" : ZahlLang(1)
       },
       "dauerhafteBetriebszeit" : {
           "ts" : Zeitstempel(1599565502, 1),
           "t" : ZahlLang(1)
       },
       "lastAppliedWallTime" : ISODate("2020-09-08T11:45:02.775Z"),
       "lastDurableWallTime" : ISODate("2020-09-08T11:45:02.775Z")
   },
   "lastStableRecoveryTimestamp" : Zeitstempel(1599565492, 1),
   "lastStableCheckpointTimestamp" : Zeitstempel(1599565492, 1),
   "Mitglieder" : [
       {
           "_id" : 0,
           "Name" : "7abd89794aa7:27017",
           "ip": "10.0.1.41",
           "Gesundheit" : 1,
           "Zustand" : 1,
           "stateStr" : "PRIMÄR",
           "Betriebszeit" : 2784,
           "optime" : {
               "ts" : Zeitstempel(1599565502, 1),
               "t" : ZahlLang(1)
           },
           "optimeDate" : ISODate("2020-09-08T11:45:02Z"),
           "syncingTo" : "",
           "syncSourceHost" : "",
           "syncSourceId" : -1,
           "infoMessage" : "",
           "Wahlzeit" : Zeitstempel(1599562790, 2),
           "Wahldatum" : ISODate("2020-09-08T10:59:50Z"),
           "Konfigurationsversion" : 3,
           "selbst" : wahr,
           "letzteHeartbeatMessage" : ""
       },
       {
           "_id" : 1,
           "Name" : "sekundär:27017",
           "ip": "10.0.1.233",
           "Gesundheit" : 1,
           "Zustand" : 2,
           "stateStr" : "SEKUNDÄR",
           "Betriebszeit" : 2711,
           "optime" : {
               "ts" : Zeitstempel(1599565502, 1),
               "t" : ZahlLang(1)
           },
           "optimeDurable" : {
               "ts" : Zeitstempel(1599565502, 1),
               "t" : ZahlLang(1)
           },
           "optimeDate" : ISODate("2020-09-08T11:45:02Z"),
           "optimeDurableDate" : ISODate("2020-09-08T11:45:02Z"),
           "lastHeartbeat" : ISODate("2020-09-08T11:45:11.494Z"),
           "lastHeartbeatRecv" : ISODate("2020-09-08T11:45:11.475Z"),
           "pingMs" : ZahlLang(0),
           "lastHeartbeatMessage" : "",
           "syncingTo" : "7abd89794aa7:27017",
           "syncSourceHost" : "7abd89794aa7:27017",
           "syncSourceId" : 0,
           "infoMessage" : "",
           "Konfigurationsversion" : 3
       },
       {
           "_id" : 2,
           "Name" : "Schiedsrichter:27017",
           "ip" : null,
           "Gesundheit" : 0,
           "Staat" : 8,
           "stateStr" : "(nicht erreichbar/fehlerhaft)",
           "Betriebszeit" : 0,
           "lastHeartbeat" : ISODate("2020-09-08T11:45:10.463Z"),
           "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
           "pingMs" : ZahlLang(0),
           "lastHeartbeatMessage" : "Fehler beim Verbinden mit Arbiter:27017 :: verursacht durch :: Adresse für Arbiter SocketException konnte nicht gefunden werden: Host nicht gefunden (autoritativ)",
           "syncingTo" : "",
           "syncSourceHost" : "",
           "syncSourceId" : -1,
           "infoMessage" : "",
           "Konfigurationsversion" : -1
       }
   ],
   "OK" : 1,
   "$clusterTime" : {
       "clusterTime" : Zeitstempel(1599565502, 1),
       "Signatur" : {
           "Hash" : BinData(0,"7/ei+8UrhlpIny9zKeWuAFpn46c="),
           "Schlüssel-ID" : NumberLong("6870069879538450434")
       }
   },
   "Operationszeit" : Zeitstempel(1599565502, 1)
}

5. Überprüfen Sie die Verfügbarkeit von MongoDB

Geben Sie zuerst den Master-Knotenserver ein, um ein Datenelement hinzuzufügen

Docker Exec -it Master Mongo
benutze den Administrator
db.auth('root', '123456')
Test verwenden
db.test.insert({name:"muyang",Alter:20})

Überprüfen Sie auf dem sekundären Knotenserver, ob die Daten synchronisiert wurden.

[root@linux sekundär] docker exec -it sekundär mongo
testSet:SECONDARY> Administrator verwenden
testSet:SECONDARY> db.auth('root', '123456')
testSet:SECONDARY> Test verwenden
testSet:SECONDARY> db.test.find()
2020-09-08T19:03:02.295+0800 E QUERY [js] nicht abgefangene Ausnahme: Fehler: listCollections fehlgeschlagen: {
   "operationTime" : Zeitstempel(1599562972, 1),
   "OK" : 0,
   "errmsg" : "nicht Master und SlaveOk=false",
   "Code" : 13435,
   "Codename" : "NichtMasterKeinSlaveOk",
   "$clusterTime" : {
       "clusterTime" : Zeitstempel(1599562972, 1),
       "Signatur" : {
           "Hash" : BinData(0,"mhsrpGHRl7qZg2QOjyS3RbBb/Yc="),
           "Schlüssel-ID" : NumberLong("6870069879538450434")
       }
   }
} :
testSet:SECONDARY> rs.slaveOk()
testSet:SECONDARY> db.users.find()
{ "_id" : ObjectId("5f5764b1f909544b783696c2"), "name" : "muyang", "alter" : 20 }

Während der sekundären Abfrage wird folgender Fehler gemeldet:

nicht Master und Slaveok=false

Das ist normal, da der Sekundärspeicher nicht lesen oder schreiben darf. Wenn Sie das Problem lösen müssen, gehen Sie wie folgt vor:

testSet:SECONDARY> rs.slaveOk()

Dies ist das Ende dieses Artikels über die Implementierungsschritte von Docker zum Erstellen eines MongoDB-Clusters. Weitere relevante Inhalte zu Docker zum Erstellen eines MongoDB-Clusters finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • So installieren Sie die neueste Version von MongoDB mit Docker
  • Versuch der Bereitstellung von Docker-Containern – Kommunikation mit mehreren Containern (Node+MongoDB+Nginx)
  • Detaillierte Erklärung zur Verwendung der MongoDB-Datenbank in Docker (Zugriff im LAN)
  • Methode zur Implementierung eines autorisierten Zugriffs auf MongoDB basierend auf Docker
  • So stellen Sie MongoDB-Container mit Docker bereit

<<:  Vue implementiert die Verpackung und Verwendung von Komponenten zur Kontrolle der Warenanzahl

>>:  Vor- und Nachteile von MySQL-Indizes und Richtlinien zum Erstellen von Indizes

Artikel empfehlen

So erstellen Sie eine MySQL-Datenbank (de1) mit Befehlen

1. Verbindung zu MySQL herstellen Format: mysql -...

Einfache Schritte zum Konfigurieren des Nginx-Reverse-Proxys mit SSL

Vorwort Ein Reverse-Proxy ist ein Server, der übe...

Implementierung der CommonJS-Modularität in Browsern ohne Kompilierung/Server

Inhaltsverzeichnis Einführung 1. Was ist one-clic...

js implementiert das Umschalten von Bildern per Maus (ohne Timer)

In diesem Artikelbeispiel wird der spezifische Co...

Linux Dateisystemtyp anzeigen Beispielmethode

So überprüfen Sie den Dateisystemtyp einer Partit...

Hinweise zu Fallstricken bei Vuex und Pinia in Vue3

Inhaltsverzeichnis einführen Installation und Ver...

Warum verwendet der MySQL-Datenbankindex den B+-Baum?

Bevor wir weiter analysieren, warum der MySQL-Dat...

Ich habe ein paar coole Designseiten zusammengestellt, die ich gut finde.

Sie müssen Inspiration haben, um eine Website zu g...

MySQL führt Befehle für externe SQL-Skriptdateien aus

Inhaltsverzeichnis 1. Erstellen Sie eine SQL-Skri...