Fallstudie – MongoDB Sharding: Wie wir unserem Kunden 100.000 € pro Jahr einsparen konnten

Unsere Open Source MongoDB Sharding-Lösung für ein skalierbares, hochverfügbares IoT-Datenbankkonzept.

In dieser Fallstudie betrachten wir MongoDB Sharding, „eine Datenbankarchitektur, die Daten nach Schlüsselbereichen partitioniert und auf zwei oder mehr Datenbankinstanzen verteilt. Sharding ermöglicht horizontale Skalierung„.

Konkret zeigen wir Schritt für Schritt, wie unser Nearshored DevOps-Team eine Open-Source-MongoDB-Sharding-Lösung für eine skalierbare, hochverfügbare verteilte Datenbank als Alternative zu einer teuren Unternehmenslizenz konfiguriert hat. Spoiler – das Nettoergebnis für unseren Kunden war eine minimale MongoDB-Unternehmenslizenz-Ersparnis von 100.000 Euro pro Jahr. Jedes Jahr.

Wir erläutern Ihnen nicht nur den Anwendungsfall (unser Kunde SolarLog ist ein führendes PV-Energiemanagementsystem), der unsere Entscheidung für die Verwendung von Open-Source-MongoDB-Code begründet, sondern beschreiben auch Schritt für Schritt den Konfigurationsprozess.

MongoDB – Auf der Suche nach dem Heiligen Gral einer automatisierten, selbstheilenden und skalierbaren Datenbanklösung

Wie effektiv Unternehmen und Organisationen Daten nutzen, ist die Grundlage für ihren nachhaltigen Erfolg und ihre Wettbewerbsfähigkeit in der heutigen Welt. Dabei kommt es auf drei Dinge an:

  • Datenerfassung
  • Datenspeicherung und -verfügbarkeit
  • Datenanalyse

Datenbanktechnologien wie MongoDB konzentrieren sich auf Nummer 2. Software-Ingenieure haben sich seit den 1970er Jahren und dem Aufkommen der relationalen SQL-Datenbanken (zuerst von IBM als „System R“-Prototyp entwickelt und 1979 von Oracle kommerzialisiert) mit den Herausforderungen bei der Entwicklung autonomer, selbst wiederherstellbarer und skalierbarer Datenbanksysteme auseinandergesetzt.

In den 1990er Jahren erschienen die objektorientierten Datenbanken, die zu NoSQL-Implementierungen führten, und dieses Format dominiert heute die Massenspeicherung von Daten im Internet. Das ursprüngliche Problem bleibt jedoch bestehen. Mit dem Aufkommen von Cloud Computing und der Verbreitung von IoT-Hardware sind Datenbanktechnologien und -systeme wichtiger denn je. Denn Daten als Währung bilden die Grundlage der digitalen Wirtschaft.

Die wichtigsten Kategorien von NoSQL-Datenbanken sind:

  • Key-Values Stores
  • Wide-Column Stores
  • Document Stores
  • Graph Databases
  • Und Search Engines

Wir konzentrieren uns hier auf Dokumentenspeicher-Datenbanken, die Daten in Form von JSON-Dokumenten speichern. Für Dokumentenspeicher ist kein festes Schema erforderlich, und die Datenstruktur kann von Dokument zu Dokument variieren. Dokumentendatenbanken verwenden dasselbe Dokumentenmodellformat, das auch in ihrem Anwendungscode verwendet wird, was es Softwareentwicklern erleichtert, die Daten in einer Datenbank zu speichern und abzufragen.

Wie von AWS erklärt:

“Die flexible, halbstrukturierte und hierarchische Natur von Dokumenten und Dokumentendatenbanken ermöglicht es ihnen, sich mit den Anforderungen der Anwendungen weiterzuentwickeln. Das Dokumentenmodell eignet sich gut für Anwendungsfälle wie Kataloge, Benutzerprofile und Content-Management-Systeme, bei denen jedes Dokument einzigartig ist und sich mit der Zeit weiterentwickelt. Dokumentendatenbanken ermöglichen eine flexible Indizierung, leistungsstarke Ad-hoc-Abfragen und Analysen über Dokumentensammlungen.”.

MongoDB, ein Open-Source-Projekt, das auch als Unternehmenslösung verfügbar ist, hat sich zu einer führenden Datenbanktechnologie für Dokumentenspeicher entwickelt, die besonders häufig in einer IoT-Umgebung eingesetzt wird.

Zu den Open-Source-Alternativen zu MongoDB gehören unter anderem CouchDB, Apache Cassandra und PostgreSQL sowie Cloud-Anbieter wie DynamoDB von AWS und AmazonDocumentDB (das mit MongoDB kompatibel ist und es in einer AWS-Umgebung unterstützen kann).

MongoDB Shards und Sharded Clusters

In MongDB werden große Datensätze durch Sharding in kleinere Teilmengen aufgeteilt, die über mehrere Instanzen verteilt sind. Diese mehreren kleineren Datensätze werden als Shards bezeichnet, die zusammen als ein großer clusterbasierter Datensatz arbeiten.

Ab MongoDB 3.6 (der neuesten Version von MongoDB 4.4) werden Shards als Replikatsatz bereitgestellt, der die für moderne Datenbanktechnologien wichtige Redundanz und Hochverfügbarkeit bietet. Shards werden von Benutzern oder Anwendungen nur für lokale Wartungs- und Verwaltungsvorgänge direkt angesprochen.

Eine Abfrage an einen einzelnen Shard gibt nur die Teilmenge der Daten zurück, die sich auf diesem Shard befinden. Bei Operationen auf Clusterebene, wie z. B. Lese- oder Schreibvorgängen, muss der Benutzer oder die Anwendung eine Verbindung zu den Mongos herstellen. Die Technologie garantiert nicht, dass zwei zusammenhängende Datenpakete auf einem einzigen Shard gespeichert werden können.

Sharding aufgeschlüsselt

Schauen wir uns die Komponenten der MongDB-Sharding-Architektur genauer an:

Primary Shard

Jede einzelne Datenbank in einem Sharded-Cluster ist um einen primären Shard zentriert. Der primäre Shard enthält alle nicht gesplitteten Sammlungen der Cluster-Datenbank. Der primäre Shard einer Datenbank ist nicht mit dem primären Shard in einem Replikatsatz verbunden.

MongoDB sharing - Primary Shard

Quelle: MongoDB

Mongos

Bei der Erstellung einer neuen Datenbank wird der primäre Shard von den Mongos als derjenige ausgewählt, der die geringste Datenmenge im Cluster enthält. Die Mongos identifizieren den primären Shard anhand des Feldes totalSize, das vom Befehl listDatabase zurückgegeben wird.

Die Schnittstelle zwischen den Client-Anwendungen und dem Shard-Cluster wird von den Mongos-Instanzen bereitgestellt, die Abfragen und Schreibvorgänge an die Shards weiterleiten. Aus Sicht einer Anwendung verhält sich eine Mongos-Instanz genau wie jede andere MongoDB-Instanz.

Ändern des primären Shards in einer Datenbank

Es ist möglich, den Shard, der einer Datenbank als primärer Shard zugewiesen ist, zu ändern, allerdings kann der Migrationsprozess einige Zeit in Anspruch nehmen, während der auf die mit der Datenbank verbundenen Sammlungen nicht zugegriffen werden sollte. Zu diesem Zweck wird der Befehl movePrimary ausgeführt.

Vor der Migration auf einen neuen primären Shard ist zu bedenken, dass größere Datensammlungen, die übertragen werden, den Betrieb eines Clusters beeinträchtigen können. Berücksichtigen Sie dies und die Netzwerkauslastung.

Bei der Bereitstellung eines neuen Sharded-Clusters mit Shards, die zuvor als Replikatsätze verwendet wurden, befinden sich die vorhandenen Datenbanken weiterhin auf ihren ursprünglichen Replikatsätzen. Datenbanken, die zu einem späteren Zeitpunkt erstellt werden, können sich auf jedem beliebigen Shard des Clusters befinden.

Shard Status

Um einen Überblick über einen Cluster zu erhalten, verwenden Sie die Methode sh.status() in der mongo shell. Der Bericht zeigt den primären Shard der Datenbank sowie die Verteilung der Datenchunks auf die Shards eines Clusters.

Sharded Cluster Security

Die Sicherheit innerhalb des Clusters wird aufrechterhalten und der unbefugte Zugriff von Komponenten wird durch die Verwendung der internen/Mitgliedschaftsauthentifizierung blockiert. Die interne Authentifizierung kann nur durchgesetzt werden, wenn jeder Mongode in einem Cluster mit den entsprechenden Sicherheitseinstellungen gestartet wird.

Shard Local Users

Die rollenbasierte Zugriffskontrolle (Role-Based Access Control, RBAC) wird auf einzelnen Shards unterstützt und schränkt den unbefugten Zugriff auf die darauf befindlichen Daten sowie die Operationen ein. Um RBAC durchzusetzen, sollte jeder Mongo im Replikatsatz mit der Option -auth initiiert werden.

Jeder Shard hat seine eigenen shard-lokalen Benutzer, die nicht auf anderen Shards oder zur Verbindung mit dem Cluster über einen Mongo verwendet werden können.

Warum Open Source MongoDB mit Sharding unsere Datenbanklösung ist

Unser Kunde SolarLog ist weltweit führend in der Innovation von Software und IoT-Geräten für die Überwachung und Verwaltung von Photovoltaikanlagen. Die Lösungen des Unternehmens werden weltweit von 327.313 PV-Anlagen in 138 Ländern genutzt. Das Unternehmen betreibt eine große Anzahl von IoT-Geräten, die die Daten der Solarenergieanlagen sammeln, deren Leistung die Produkte und Lösungen des Unternehmens optimieren sollen.

Nach der teilweisen Verarbeitung mussten diese großen und wachsenden Datenströme effizient gespeichert und einfach und zuverlässig zugänglich gemacht werden. Skalierbarkeit war eine Voraussetzung, ebenso wie die Fähigkeit zur Selbstheilung. Die Last musste auf die Clusterknoten verteilt werden, um eine hohe Verfügbarkeit und Wiederherstellbarkeit zu gewährleisten.

Unser Team entschied sich für die Entwicklung der Datenbank unter Verwendung von Open Source MongoDB Sharding. Die einfache Alternative wäre eine MongoDB-Unternehmenslizenz gewesen. Diese hätte jedoch Kosten in Höhe von 100.000 € pro Jahr verursacht, ohne Berücksichtigung der Serverkosten.

Wir waren zuversichtlich, dass eine Konfiguration, die den Open-Source-Code von MongoDB und Sharding zur effektiven Verteilung auf Knoten-Cluster nutzt, die Anforderungen des Projekts vollständig erfüllen würde, und machten uns an die Umsetzung.

Problemlösung – Was wir bei der Konfiguration unserer MongoDB-Sharding-Lösung gelernt haben

Kein Projekt, das eine relativ komplexe benutzerdefinierte Architektur und Entwicklung beinhaltet, wird erfolgreich durchgeführt, ohne dass Probleme auftauchen. Diese spezielle Datenbanklösung bildete da keine Ausnahme. Ursprünglich wurde ein falscher Ansatz für die Erstellung von Backups gewählt. In der endgültigen Version der Lösung wurde das Schema so angepasst, dass Schnappschüsse des Dateisystems erstellt wurden, wobei die Datenbankeinträge in dem Moment gesperrt wurden, in dem die Schnappschüsse erstellt wurden. Meinste ich

MongoDB Sharding-Cluster-Konfiguration: Schritt-für-Schritt-Einrichtung

In unserer Konfiguration werden wir das folgende Schema verwenden:

MongoDB sharding architecture - cluster configuration diagram

Der Ausgangspunkt ist die Installation der mongosb-Daemons auf den Config-Servern

config of the first CFG replica set server for mongo

systemLog:

  destination: file

  logAppend: true

  path: /var/log/mongodb/mongod.log

 

storage:

  dbPath: /var/lib/mongo

  journal:

    enabled: true

 

processManagement:

  fork: true

  pidFilePath: /var/run/mongodb/mongod.pid

  timeZoneInfo: /usr/share/zoneinfo

 

net:

  port: 27017

  bindIp: mongos-cfg1

 

replication:

   oplogSizeMB: 10240

   replSetName: "replconfig01"

 

sharding:

   clusterRole: configsvr

Für die anderen beiden cfg-Server ist alles ähnlich, wir ändern nur bindIP

Wenn Sie kurze Namen von Clustermitgliedern verwenden, geben Sie diese in der Datei /etc/hosts an

Wir verbinden uns mit unserem ersten Server mongodb-cfg1 und erstellen ein replicaset

mongo --host mongos-cfg1 --port 27017

Befehl ausführen;

rs.initiate(

  {

    _id: "replconfig01",

    configsvr: true,

    members: [

      { _id : 0, host : "mongos-cfg1:27017" },

      { _id : 1, host : "mongos-cfg2:27017" },

      { _id : 2, host : "mongos-cfg3:27017" }

    ]

  }

)

MongoDB cluster configuration - sharding

In der Ausgabe „ok“: 1 – bedeutet die erfolgreiche Ausführung unseres vorherigen Befehls.

Wir überprüfen den Status aller drei Server, es sollte 1 Primary und 2 Secondary geben, die Befehle zur Überprüfung des Status:

rs.isMaster()

rs.status()

Wir konfigurieren unseren Shard für MongoDB, die Konfiguration des ersten Shards:

systemLog:

  destination: file

  logAppend: true

  path: /var/log/mongodb/mongod.log
storage:

  dbPath: /opt/mongo

  journal:

    enabled: true
processManagement:

  fork: true  # fork and run in background

  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile

  timeZoneInfo: /usr/share/zoneinfo
net:

  port: 27017

  bindIp: 0.0.0.0
security:

  authorization: enabled

 

security:

    transitionToAuth: false

    keyFile: /etc/mongo.keyfile

 

replication:

    replSetName: "rs1"

 

sharding:

   clusterRole: shardsvr

Generiere keyfile:

openssl rand -base64 756 > /etc/mongo.keyfile

chmod 400 /etc/mongo.keyfile

Setzen Sie für das durch dbPath angegebene Mongo-Datenspeicherverzeichnis den richtigen Eigentümer:

chown -R mongod:mongod /opt/mongo/

Wir starten die Dienste und überprüfen, ob die benötigten Daemons auf Port 27017 lauschen.

Wir führen Befehle aus, um das erste Replikat, den ersten Shard, zu initialisieren:

rs.initiate(

  {

    _id: "rs1",

    members: [

      { _id : 0, host : "ip_mongo_shard_1_1:27017" },

      { _id : 1, host : " ip_mongo_shard_1_2:27017" },

      { _id : 2, host : " ip_mongo_shard_1_3:27017" }

    ]

  }

)

Der letzte und interessanteste Punkt ist die Einrichtung von mongos – ein Router für alle Anfragen an unseren zukünftigen Cluster.

Nachdem das mongod-Paket auf dem zukünftigen Router installiert ist, erstellen wir eine Servicedatei, damit mongos automatisch startet

!!! The mongod service itself must be stopped and excluded from autorun !!!

nano /etc/systemd/system/mongos.service


[Unit]

Description=High-performance, schema-free document-oriented database

After=network.target

Documentation=https://docs.mongodb.org/manual

 

[Service]

Type=forking

User=root

Group=root

ExecStart=/usr/bin/mongos -f /etc/mongos.conf

PIDFile=/var/run/mongos.pid

LimitFSIZE=infinity

LimitCPU=infinity

LimitAS=infinity

LimitNOFILE=64000

LimitNPROC=64000

LimitMEMLOCK=infinity

TasksMax=infinity

TasksAccounting=false

 

[Install]

WantedBy=multi-user.target

Den Befehl ausführen um die Liste des Services zu aktualisieren

systemctl daemon-reload

systemctl enable mongos

Unsere config Datei für mongos /etc/mongos.conf will be as follows:

:systemLog

  destination: file

  logAppend: true

  path: /var/log/mongodb/mongos.log

 

processManagement:

  fork: true

  pidFilePath: /var/run/mongos.pid

  timeZoneInfo: /usr/share/zoneinfo

 

net:

  port: 27017

  bindIp: 0.0.0.0

  maxIncomingConnections: 20000

  ipv6: false

 

sharding:

  configDB: "replconfig01/ mongos-cfg1:27017, mongos-cfg2:27017, mongos-cfg3:27017"

 

security:

  keyFile: /etc/mongo.keyfile

Auf mongos server wiederholen Sie die Schritte zum Erstellen des keyfile.

Run den Mongos service

systemctl start mongos

Check:

netstat -ntupl | grep mongos

tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      3570/mongos

Also in the log /var/log/mongodb/mongos.log there should be lines with a successful connection to our config replicaset mongo

Successfully connected to mongos-cfg1:27017

Successfully connected to mongos-cfg2:27017

Successfully connected to mongos-cfg3:27017

Der letzte Schliff, die Regierung unserer mongo shard Server im mongos router

Verbinden Sie sich auf dem mongos server mit unserem cluster:

mongo --host mongos --port 27017

und füge unseren shard server hinzu:

sh.addShard("rs1/ ip_mongo_shard_1_1:27017, ip_mongo_shard_1_2:27017, ip_mongo_shard_1_3:27017")

und fügen weitere hinzu, wenn du sie erstellst:

sh.addShard("rs2/ ip_mongo_shard_2_1:27017, ip_mongo_shard_2_2:27017, ip_mongo_shard_2_3:27017")

sh.addShard("rs3/ ip_mongo_shard_3_1:27017, ip_mongo_shard_3_2:27017, ip_mongo_shard_3_3:27017")

…

MongoDB Sharding Fallstudie: Fazit

Unsere Lösung für SolarLog ist nicht bahnbrechend in dem Sinne, dass wir mit dem Open-Source-Code von MongoDB nichts getan haben, was nicht schon vorher gemacht wurde. Unser MongoDB-Sharding-Ansatz für Cluster entspricht jedoch voll und ganz den Anforderungen des Projekts und zeigt, wie die oft hohen Kosten für Unternehmenslizenzen mit ein wenig Nachdenken und Innovation vermieden werden können.

Die Bezahlung von Unternehmenslösungen kann eine bequeme Option sein, wenn das Geld vorhanden ist und der Business Case den Aufwand rechtfertigt. Aber es ist auch nicht notwendig, insbesondere im Fall von ausgereiften, gut entwickelten und mit Ressourcen ausgestatteten Open-Source-Technologien. Eine Open-Source-Alternative, insbesondere eine, die über die Lebensdauer einer Datenbankarchitektur zu Kosteneinsparungen von bis zu 1 Mio. € führen kann, ist fast immer eine Überlegung und Prüfung wert.

Ausgewählte Blogbeiträge