MongoDB Profiling

In den meisten unserer Produkte übernimmt im Hintergrund eine MongoDB die Datenspeicherung. Im Gegensatz zu relationalen Datenbanken, wie z.B. MySQL, kommt die MongoDB ohne festes Schema daher, sondern kann komplex verschachtelte Strukturen speichern. Dennoch haben beide Datenbanken eines gemeinsam: Mit Indizes gehen Abfragen schlichtweg deutlich schneller, da indizierte Daten im Speicher behalten werden und somit nicht bei jeder Abfrage erneut von der Festplatte gelesen werden müssen. Dementsprechend sind Indizes sehr RAM-lastig und damit teurer, als herkömmlicher Festplattenplatz und sollten wohl gewählt sein.​​

Im Zuge der kontinuierlichen Weiterentwicklung unseres Produkt, dem CMS .Stone haben wir uns die Datenbank-Einstellungen noch mal genauer angeschaut. Auch wenn wir bisher keine Probleme mit der Ladegeschwindigkeit irgendwelcher Seiten hatten, interessierte uns, wie schnell und einfach wir ggf. eine bisschen bessere Performance erreichen könnten.

Dabei konzentrierten wir uns auf die häufigsten Abfragen auf der Datenbank, um eben dort speziell über Indizes einige Millisekunden gewinnen zu können. Das Ergebnis konnte sich sehen lassen! Zwei elementare Indizes auf einer Collection sparten uns bei jedem Seitenaufruf rund 250ms - also eine Beschleunigung von 25% zur bisherigen Ladegeschwindigkeit.

MongoDB bringt glücklicherweise ein einfaches Diagnosewerkzeug mit, mittels dessen die potentiell langsamen Abfragen protokolliert werden können. Dies entsprecht in etwa dem sog. Slowlog in MySQL. Es lässt sich ein Profiler aktivieren, der sämtliche Abfragen, die langsamer als ein angegebener Schwellwert sind, protokolliert. Selbstverständlich werden die Daten in eine Collection innerhalb der Datenbank selbst geschrieben - damit können wir effizient die für uns relevanten Daten heraussuchen.

Diese Collection namens “system.profile” legt standardmäßig die MongoDB selbst an, sobald der Profiler aktiviert wird. Wir greifen aber der MongoDB vorweg und legen selbst explizit eine “Capped Collection” an, die nicht mehr als die angegebene Größe bzw. Anzahl an Einträgen speichert, andernfalls könnte zu Spitzenzeiten bei der großen Menge an CMS-Aufrufe schnell die Collection ins Unermessliche volllaufen. Wir gestatten maximal 10.000 Einträge bei einem Speicherverbrauch von maximal rund 5 MB.

db.createCollection("system.profile", { capped : true, size : 5242880, max : 10000 } )

Anschließend aktivieren wir den Profiler:​​

db.setProfilingLevel(1, 1)

Die erste Zahl bezieht sich hierbei auf den Level (0 - aus, 1 - nur “langsame Abfragen”, 2 - alle Abfragen), während der zweite Wert die “langsame Abfrage” in Millisekunden definiert. Wir möchten also in unserem Beispiel alle Abfragen die länger als 1ms dauern in unserer Collection protokolliert bekommen. Wir haben uns bewusst für nur eine Millisekunde entschieden, da wir durchaus für unser CMS den Anspruch hegen, dass alle der häufig verwendeten Abfragen aus dem Index kommen muss. Weiterhin ist gerade für Websites die Ladezeit äußerst wichtig, da Google schnelle Webseiten in ihren Suchergebnissen belohnt.

Weitere Links:

Dennis Oehme, Geschäftsführer bei Garden of Concepts GmbH

Dennis Oehme via
@goc_mediastudio

Geschäftsführer

Dennis Amerika, Reisen, Fotografie, Programmiersprachen, Mobile Apps, Blogging, Bücher, Frittiertes, Wasser, Politik, Konferenzen, Camping, Dronen, Serien, Ironie, Debattieren

Kontakt aufnehmen


Garden of Concepts GmbH

Josef-Bautz-Straße 14
63457Hanau

Phone: 06181 / 9661660
Fax: 06181 / 9661665

studio@goc.email