Das Erlernen von MongoDB erfordert viel genaues Denken. Bei wesentlichen Unternehmungen, die sonst die Leistungsfähigkeit der Datenbank im Produktivbetrieb gefährden könnten, wird oft wenig Rücksicht genommen.
MongoDB ist ein NoSQL-DBMS, das buchstäblich einem anderen Muster als SQL-Datenbanken folgt, insbesondere in Bezug auf Sicherheit und Struktur. Obwohl einige der integrierten Funktionen seine Leistung fördern und es zu einem der besten der letzten Zeit machen, stellen einige der Funktionen folglich potenzielle Bedrohungen dar, die seine Leistung ruinieren können, wenn sie nicht berücksichtigt werden.
Bei einem kürzlichen „Worst-Case“-Erlebnis versuchte ich, eine Sammlung mit Dokumenten abzufragen, die große Arrays hatten, und es dauerte ewig, bis ich die Ergebnisse zurückbekam. Ich habe mich entschieden, diesen Blog zu schreiben, da ich wusste, dass dieser Blog eine große Hilfe sein wird, wenn jemand dieselben Probleme hat.
Wichtige Überlegungen zu MongoDB in der Produktion
- Sicherheit und Authentifizierung.
- Indizierung Ihrer Dokumente
- Ein Schema in Ihren Sammlungen verwenden
- Begrenzte Sammlung
- Dokumentgröße
- Array-Größe für eingebettete Dokumente
- Phasen der Aggregationspipeline
- Reihenfolge der Schlüssel im Hash-Objekt
- ‚undefiniert‘ und ‚null‘ in MongoDB
- Schreibvorgang
MongoDB-Sicherheit und -Authentifizierung
Daten variieren in vielerlei Hinsicht und einige Informationen müssen natürlich vertraulich behandelt werden. Standardmäßig setzen MongoDB-Installationen keine Authentifizierungsanforderung als Muss, aber das gibt Ihnen keine Möglichkeit, sie zu verwenden, insbesondere wenn vertrauliche Daten wie Finanz- und Krankenakten betroffen sind. Auf einer Entwicklungs-Workstation ist dies keine große Sache, aber aufgrund der Beteiligung mehrerer Benutzer im Produktionsmodus ist es eine gute Praxis, die Authentifizierungszertifikate festzulegen. Die gebräuchlichste und am einfachsten zu verwendende Methode sind die standardmäßigen Anmeldeinformationen für MongoDB-Benutzername und -Kennwort.
Daten werden in Dateien geschrieben, auf die über ein Drittanbieter-Tool zugegriffen werden kann, umso mehr, wenn sie nicht verschlüsselt sind. Die Daten können ohne Ihr Wissen geändert werden, wenn eine anonyme Person Zugriff auf die Systemdateien erhält. Wenn Sie die Datenbank auf einem dedizierten Server hosten und einen einzigen Benutzer zuweisen, der vollen Zugriff auf die Datendateien hat, sparen Sie sich den Trick.
Der Schutz von Daten vor externen Einschleusungsangriffen ist ebenfalls ein wesentliches Unterfangen. Einige Operatoren wie $group, $whereby und die mapReduce-Operationen sind mit Javascript (js) entwickelt und daher anfällig für js-Manipulationen. Um jegliche Datenintegrität zu vermeiden, können Sie beliebige JS-Einstellungen deaktivieren, indem Sie den Parameter javascriptEnabled:false in der Konfigurationsdatei konfigurieren, wenn Sie keinen der genannten Operatoren verwendet haben. Darüber hinaus können Sie das Risiko des Datenzugriffs durch Netzwerkverletzungen verringern, indem Sie einige der in der MongoDB-Sicherheitscheckliste aufgeführten Verfahren anwenden.
Indizierung Ihrer Dokumente
Bei der Indizierung wird im Allgemeinen jedem Dokument in einer MongoDB-Sammlung ein eindeutiger Identifikationswert zugewiesen. Die Indizierung bewirkt eine Leistungssteigerung sowohl bei Lese- als auch bei Schreibvorgängen. Standardmäßig ist es aktiviert und man sollte diese Einstellung immer beibehalten. Ohne Indizierung muss die Datenbank mehrere Dokumente von Anfang bis Ende durchgehen, und leider wird der Vorgang für Dokumente, die sich gegen Ende befinden, zeitaufwändig, was zu einer schlechten Latenz für die Abfrage führt. Irgendwann können Benutzer auf der Anwendungsseite eine Verzögerung feststellen und denken, dass die Anwendung tatsächlich nicht funktioniert. Die Indizierung ist hilfreich bei Sortier- und Suchabfrageoperationen, wobei die Suchoperation selbst nicht ausgelassen wird. Das Sortieren ist ein üblicher Vorgang für viele zurückgegebene Dokumente. Es wird oft als letzter Schritt durchgeführt, nachdem Dokumente gefiltert wurden, so dass eine kleine Menge von Daten sortiert werden muss. Ein Index hilft in diesem Fall dabei, die Daten nach Art der Eingabe zu sortieren und die zurückgegebenen Daten auf eine Grenze von 32 MB zu beschränken. Wenn es keine Indizierung gibt, wird die Wahrscheinlichkeit, dass die Speichergrenze von 32 für die kombinierte Größe der zurückgegebenen Dokumente überschritten wird, und immer wenn die Datenbank diese Grenze erreicht, wird neben der Rückgabe eines leeren Datensatzes ein Fehler ausgegeben.
Die$lookup-Operation wird auch mit vorhandener Indizierung unterstützt. Ein Index für den als Fremdschlüssel verwendeten Schlüsselwert ist für die Verarbeitung in den vorangehenden Phasen unerlässlich.
Ein Schema in Ihren Sammlungen verwenden
MongoDB benötigt keine, um Felder (Spalten) zu definieren, so wie Sie es möglicherweise für SQL-DBMS tun müssen. Auch wenn Sie die Felder nicht definieren müssen, um Dateninkonsistenzen und eventuell auftretende Rückschläge zu vermeiden, ist das Definieren eines Schemas immer eine gute Vorgehensweise. Mit dem Schemadesign können Sie bestimmen, welche Art von Daten in ein bestimmtes Feld gehen, welches Feld mit einem Wert versorgt werden muss, und im Allgemeinen die Datenvalidierung vor der Eingabe oder Aktualisierung verbessern, wodurch die Datenintegrität und -konsistenz gefördert wird. Ein Schemaentwurf weist Sie auch an, ob Daten referenziert oder eingebettet werden sollen. Als Anfänger denken Sie vielleicht, dass das einzige Modell „Eins-zu-N“ sein wird, das es einem erleichtert, Array-Einträge für Unterdokumente zu haben, aber das ist nicht der Fall.
Sie müssen die Kardinalitätsbeziehung zwischen Dokumenten verstehen, bevor Sie Ihr Modell erstellen. Einige der Regeln, die Ihnen helfen, ein optimales Schema zu haben, sind:
- Um die Anzahl der Abfragen zu reduzieren, die Sie ausführen müssen, bevor Sie auf einige Daten zugreifen, und wenn nur wenige Felder oder Array-Elemente betroffen sind, können Sie Filialdokumente einbetten. Nehmen Sie ein Beispiel für das folgende Modell:
-
{ Name: ‘John Doh’, Age:20 Addresses:[ {street: ‘Moi Avenue’, city:’Nairobi’, countryCode: ‘KE’}, {street: ‘Kenyatta Avenue’, city:’Nairobi’, countryCode: ‘KE’}, ] }
-
- Verwenden Sie für häufig aktualisierte Dokumente die Denormalisierung . Wenn ein Feld häufig aktualisiert werden soll, besteht die Aufgabe darin, alle Instanzen zu finden, die aktualisiert werden müssen. Dies führt zu einer langsamen Abfrageverarbeitung, wodurch sogar die mit der Denormalisierung verbundenen Vorteile überwältigt werden.
- Komplexe Abfragen wie aggregiertes Pipelining nehmen mehr Zeit in Anspruch, wenn viele Unterdokumente beteiligt sind und ein Dokument separat abgerufen werden muss.
- Array-Elemente mit einem großen Satz von Objektdaten sollten nicht offensichtlich eingebettet werden, da sie wachsen und folglich die Dokumentgröße überschreiten können.
Die Modellierung eines Schemas wird häufig durch das Anwendungszugriffsmuster bestimmt. Weitere Vorgehensweisen, die Ihnen beim Design Ihres Modells helfen können, finden Sie im Blog 6 Faustregeln für das Schemadesign von MongoDB
Verwenden Sie eine begrenzte Sammlung für die Priorität der letzten Dokumente
MongoDB bietet viele Ressourcen, wie z. B. die begrenzte Sammlung. Leider werden einige am Ende nicht genutzt. Eine begrenzte Sammlung hat eine feste Größe und unterstützt bekanntermaßen Vorgänge mit hohem Durchsatz, bei denen Dokumente basierend auf der Einfügungsreihenfolge eingefügt und abgerufen werden. Wenn der Speicherplatz voll ist, werden alte Dokumente gelöscht, um Platz für neue zu schaffen.
Beispiel für den Anwendungsfall einer begrenzten Sammlung:
- Caching von häufig aufgerufenen Daten, da die Sammlung selbst eher lese- als schreiblastig ist. Sie müssen sicherstellen, dass die Sammlung immer funktioniert.
- Protokollinformationen für hochvolumige Systeme. Gedeckelte Sammlungen verwenden oft keinen Index und das hat den Vorteil, dass die Aufzeichnungsgeschwindigkeit ziemlich schnell ist, genau wie beim Schreiben in eine Datei.
Achten Sie auf die MongoDB-Dokumentgröße
Jedes MongoDB-Dokument ist auf eine Größe von 16 Megabyte begrenzt. Es ist jedoch optimal, wenn das Dokument diese Grenze erreicht oder sich ihr nähert, da dies einige schreckliche Leistungsprobleme mit sich bringt. MongoDB selbst funktioniert am besten, wenn die Größe der Dokumente einige Kilobyte beträgt. Wenn das Dokument groß genug ist, dauert eine komplexe Projektionsanfrage lange und die Abfrage kann eine Zeitüberschreitung aufweisen.
Achten Sie auf die Array-Größe eingebetteter Dokumente
Man kann Unterdokumente in ein Feld in einem Dokument verschieben und dadurch einen Array-Wert für dieses Feld erstellen. Wie bereits erwähnt, müssen Sie die Größe der Filialdokumente gering halten. Ebenso wichtig ist es sicherzustellen, dass die Anzahl der Array-Elemente unter einer vierstelligen Zahl liegt. Andernfalls wächst das Dokument über seine Größe hinaus und muss auf der Festplatte verschoben werden. Ein weiteres mit einer solchen Operation verbundenes Problem besteht darin, dass jedes Dokument neu indiziert werden muss. Außerdem muss jedes untergeordnete Dokument gleichermaßen neu indiziert werden. Dies bedeutet, dass es viele Indexschreibvorgänge geben wird, was zu langsamen Operationen führt. Bei großen Unterdokumenten ist es eher wichtig, die Datensätze in einer neuen Sammlung zu behalten, als sie einzubetten.
Phasen der Aggregationspipeline
Neben den normalen MongoDB-Abfrageoperationen gibt es ein Aggregations-Framework, das verwendet wird, um Daten in Übereinstimmung mit einigen Spezifikationen wie Sortierung und Gruppierung zu manipulieren und zurückzugeben. MongoDB hat keinen Abfrageoptimierer und benötigt daher einen, um Abfragen entsprechend zu ordnen. Stellen Sie mit dem Aggregations-Framework sicher, dass die Pipeline-Phasen gut geordnet sind. Reduzieren Sie zunächst die Datenmenge, mit der Sie es zu tun haben, indem Sie den $match-Operator und möglicherweise $sort am Ende verwenden, wenn eine Sortierung erforderlich ist. Sie können Tools von Drittanbietern wie Studio 3T verwenden, um Ihre Aggregationsabfrage zu optimieren, bevor Sie sie in Ihren Code integrieren. Das Tool ermöglicht es Ihnen, die Dateneingabe und -ausgabe in jeder Phase zu sehen, sodass Sie wissen, womit Sie es zu tun haben.
Die Verwendung von $limit und $sort sollte bei jeder Ausführung der Abfrage immer dieselben Ergebnisse liefern. Falls Sie $limit verwenden, sind die zurückgegebenen Daten nicht deterministisch und können einige Probleme verursachen, die schwer nachzuverfolgen sind.
Überprüfen Sie die Reihenfolge der Schlüssel in Hash-Objekten
Erwägen Sie, zwei große Dokumente mit Beispieldaten zu haben
{
FirstName: ‘John’,
LastName: ‘Doh’
}
Wenn Sie eine Suchoperation mit der Abfrage {FirstName:'John', LastName:'Doh'} durchführen, stimmt die Operation nicht mit der Abfrage {LastName:'Doh' FirstName:'John' überein }. Daher müssen Sie die Reihenfolge der Namens- und Wertepaare in Ihren Dokumenten beibehalten.
Vermeiden Sie „undefined“ und „null“ in MongoDB
MongoDB verwendet das BSON-Format für seine Dokumente. Bei der JSON-Validierung wird „undefined“ nicht unterstützt und Sie sollten es vermeiden. $null kommt als Lösung, aber Sie sollten es auch vermeiden.
Berücksichtigen Sie Schreibvorgänge
Sie könnten MongoDB für Hochgeschwindigkeitsschreibvorgänge einstellen, aber dies stellt einen Rückschlag dar, da eine Antwort zurückgegeben wird, noch bevor die Daten geschrieben werden. Journaling sollte aktiviert werden, um dieses Szenario zu vermeiden. Darüber hinaus sind die Daten im Falle eines Datenbankausfalls weiterhin verfügbar und es wird ein Prüfpunkt erstellt, der im Wiederherstellungsprozess verwendet werden kann. Die Konfiguration für die Dauer von Journal Writes kann über den Parameter commitIntervalMs.
gesetzt werdenFazit
Das Datenbanksystem sollte die Datenintegrität und -konsistenz gewährleisten und außerdem widerstandsfähig gegen Ausfälle und Böswilligkeit sein. Um zu diesen Faktoren zu gelangen, muss man jedoch die Datenbank selbst und die darin enthaltenen Daten verstehen. MongoDB wird gut funktionieren, wenn die oben genannten Faktoren berücksichtigt werden. Das wichtigste davon ist die Verwendung eines Schemas. Ein Schema ermöglicht es Ihnen, Ihre Daten vor der Eingabe oder Aktualisierung zu validieren und wie Sie diese Daten modellieren. Die Datenmodellierung wird häufig durch das Zugriffsmuster der Anwendung gesteuert. All dies zusammen ergibt eine bessere Datenbankleistung.