Extra Blog

Tschäck des Todes, oder wenn die Performancemessung die Systeme lähmt.

dann ist es mal wieder Zeit zu prüfen, wo die groben Schnitzer versteckt sind.

 Konkret ging es um eine Implementierung / Ablösung von Cacti durch Icinga /check_mk und pnp4nagios. Warum gerade so, weiss kein Mensch aber wurde so gefordert. Das Ergebnis war, mehrere Checks die es als Temples und Plugins für cacti gab, für Icinga bzw. als check_mk Checks um zu schreiben.

Ein Werkstudent sollte dies erledigen. Gut, dass man mal drüber geschaut hat. 

Insgesamt sollten rund 100 Werte einer Datenbank visualisiert werden, also als Graph ausgezeichnet werden.

Dies wiederum von mehreren Datenbanksystemen wessen Anzahl nicht näher spezifiziert ist.

Je nach check werden zwischen 1 -10 Parameter abgerufen und ausgewertet. Alle Werte werden aus der Ausgabe von: show global status; show variables; show engine innodb status; ermittelt.

Der gesamte Aufbau der Abfragen und Checks war nun etwas "unüberlegt" realisiert worden.

Es wurden rund 10 Scripte angelegt welche die jeweiligen Daten aufbereiten sollten. In jedem der Scripte wurden je nach Anforderung zwischen 1-10 Werte abgefragt.

2 Dinge wurde jedoch falsch angegangen. Zum einen wurden die Daten mit hohem aufwand ermittelt.

Für jeden Datensatz wurde eine Datenbankverbindung abgesetzt, eine Abfrage wie: "show global status" abgesetzt und der zu ermittelnde Wert per grep gezogen.

Quasi: mysql -e "show global status" | grep Innodb_buffer_pool_read_requests | awk .....

Insgesamt wären also remote je Datenbanksystem 100 Verbindungen notwendig geworden.

Sieht man sich an, wie lange jede Abfrage dauert z.B. mit time:

time mysql -e "show global status" | grep Innodb_buffer_pool_read_requests 

erhält man ein realistisches Bild darüber:

real 0m0.011s

user 0m0.004s

sys 0m0.000s

Der lokale Zugriff auf das Filesystem um z.B. temporäre Daten aus der vorherigen abfrage aus zu werten geht bedeutend schneller.

grep Threads test.txt

Threads_cached 6

Threads_connected 6

Threads_created 12

Threads_running 2

real 0m0.001s

user 0m0.000s

sys 0m0.000s

Würde man also jeden Wert einzeln abrufen, wie ursprünglich programmiert, dann würde die Ausführung 100*  0.011 Sekunden dauern also ca. 1,1 Sekunden. 

Jetzt optimieren wir wie folgt:

Je Datenbank werden alle 3 Informationen abgerufen. Es wird nur eine Verbindung geöffnet.

time mysql -e "show global status;show variables; show engine innodb status"  > temp.txt

dauerte, mit 15 Wiederholungen getestet, gleich lang.

real 0m0.011s

user 0m0.004s

sys 0m0.000s

Jetzt werten wir diese Daten entsprechend aus bzw. ermitteln die für uns relevante Daten

egrep "(Threads_cached|Threads_connected|Threads_created|Threads_running)" temp.txt

Von Ursprünglich insgesamt 100 Datenbankabfragen haben wir die Scripte auf 1 Datenbankabfrage sowie 10 Filezugriffe lokal reduziert.

Zusammen gerechnet 0.021 s vs. 1,1 s.

In der gleichen Zeit von 1,1 Sekunden kann man nun 52 Datenbanken Messen an Stelle von nur einer. Gelegentlich macht es also durchaus Sinn zu überlegen ob man einen besseren Weg nutzen kann. 

Als Gegenargument wurde angenommen, es stimme dann möglicherweise die Statistik nicht mehr sauber überein.

Wenn man betrachtet, dass vorher für die gesamte Messsreihe ca. 1,1 Sekunden vergangen sind, danach für die gesamte Auswertung der Messreihe nur noch 20ms (1 ms je check insgesamt ca. 10 Checks) sowie die Ermittlung der Daten rund 11 ms dauerte, man muss berücksichtigen, dass die Daten seitens DB innerhalb weniger ms 1-2 ermittelt wurden, hingegen der Overhead um die Verbindung her zu stellen, den Rest der Zeit benötigt, dann ist auch dieser Datenstamm zeitlich viel dichter beieinander,als vorher. Das Ergebnis durch die zeitliche Nähe bedeutend exakter. 

Buchempfehlung:  Unix Power Tools.

Kategorien: IT

Noch keine Kommentare

Die Kommentarfunktion wurde vom Besitzer dieses Blogs in diesem Eintrag deaktiviert.