Extra Blog

Teil 1 Mysql / DB Optimierung oder: Das Projekt des Grauens

"Hilfe, meine Anwendung ist sooooooo langsam." Schallte es kürzlich aus dem Telefon. "Was kann man machen, das muss schnellstens wieder schnell sein."

Ewig gestrig  wie ich nun mal bin, sagte ich dem potentiellen Kunden erstmal ab und klärte Ihn darüber auf, dass es keine kurzfristige und vor allem, langfristige zufriedenstellende Lösung auf die schnelle gibt. Alles andere ist dann Glück, welches auch mir ab und an vergönnt sein möge. Aber das erfährt man erst, wenn man sich das System genauer angesehen hat.  Mit gewisser Häme in der Stimme: "Wir haben das Problem nun gelöst. Sie müssen sich also keine Zeit frei schaufeln." sagte man mir den Termin kurzfristig ab. Ich habe mir trotzdem die Zeit frei gearbeitet. Denn es kam, wie es wohl kommen musste:

Eddy rief mich wenige Tage später an. Eddy eine Freelancer, mit dem ich gelegentlich zusammen arbeite. Er ist aber im Gegensatz zu mir, ein kreativer Künstler (Pixelschuppser).

 "Meister W*,ich habe da einen verzweifelten Kunden an der Hand. Der hat erhebliche Performance Probleme. Ist doch genau Dein Ding. Hättest Du Zeit?" Natürlich hatte ich Zeit. Ich ahnte auch schon um wen es ging.

Der Grundstein sei also gelegt, für das Thema "aus langsam mach schnell".

 Zuerst einmal stellt sich die Gretchenfrage, wie ist der jetzt Zustand des Systems? Kann man kurzfristig für Entlastung sorgen, so dass die wichtigsten Dienste zügig laufen und es somit zu keinem Umsatzeinbruch kommt? Ja, das war technisch möglich. Emotional und politisch war es allerdings eine Hochleistung dem Vorstand klar zu machen, dass es den Ist Zustand aus der "Produktion" so erst mal nicht mehr gibt sondern nur noch einen bis zu 15 min. alten Stand. Auch der Versuch in Echtzeit das DWH zu befüttern wurde abgestellt.

Macht ohnehin nur bedingt Sinn.

Die Auswirkung war beinahe wie das einholen eines Ankers. Dieser Stand durfte nicht lange so bleiben, allerdings ergab sich somit genug Zeit für die weitere Analyse. Das System war für die Hardware ausreichend konfiguriert. Den Optimierungen an Speicher, Caches und Co wollte ich mich später widmen.

Ins Auge gestochen sind folgende Punkte:

Eine Hohe IO, sehr viele parallele Datenbank Prozesse und damit verbunden auch viele Locks auf einzelne Tabellen. Wie kommt man der Sache auf die Schliche?

Zum einen reicht ein Blick in die mysql Konsole und die Abfrage:

show full prozesslist;

 Tauchen hier mehrere Zeilen / "Abfragen" im status running bzw. query auf, sollte man sich die Abfragen genauer ansehen. Betreffen Sie alle die gleiche Tabelle, wäre auch zu prüfen. bo sich diese Gegenseitig blockieren.Als Fausformel kann man sagen, dass bis ca. 10 gleichzeitige Prozesse (auf Linux Systemen), so denn sie sich nicht gegenseitig Blockieren, auf einer Mysql 4 -5.1 noch i.O. sind. Ab Mysql 5.5 sind angeblich bis zu 30 Prozesse unproblematisch. Für Solaris verdoppelt sich die Anzahl der Parallelen Prozesse.

Man muss aber auch klar dazu sagen, Prozess ist nicht gleich Prozess. Komplexe Abfragen können durchaus einen Core vollständig in Beschlag nehmen. Ist dieser Fall allerdings gegeben, steigt die Load und auch die Anzahl auflaufender Prozesse rapide an. Es kommt zunehmend zu abbrüchen und Spürbaren Engpässen.

  Die obigen Werte beziehen sich auf Messwerte über mehrere Stunden. Kurzfristige Schwankungen sind eher seltener ein Problem. Auch bricht das System nicht mit steigender und mehr parallelen Prozessen unmittelbar zusammen. Es bringen aber "100" Cores auf einer Linux Umgebung nichts, denn Mysql wird in früheren Versionen als 5.5 zunehmend ineffizient in der Threadverwaltung weshalb die genannten 10 Prozesse noch i.o. sind. Darüber hinaus wird i.d.R. mehr Rechenleistung für die Verwaltung der Threads als deren Abarbeitung benötigt. Zurück zum Thema.

 Einige Probleme sind mir sofort aufgefallen. 3 Tabellen waren mit hoher Write Rate belastet. Ein Klassiker aller Webanwendungen ist doch immer dabei: counter, statistics, sessions. Durch die hohe Besucherzahlen, waren Zähler von Massenhaft updates betroffen. Leider kennt MyIsam kein Zeilen basiertes Sperren. Daher mussten die Updates immer auf das vorhergehende Update warten. Das ganze ging bei wenige Besuchern und wenigen Datensätzen lange gut. Aber die Kombination aus hoher Besucherantdrang und steigende Datenmenge machte das ganze extrem langsam. Eine etwas ungeschickte Indizierung verschärfte die Lage zusätzlich. Eine Umstellung von MyIsam auf InnoDB verschaffte insofern Abhilfe, dass die Abfragen deutlich seltener in der Prozessliste auftauchten und meistens nur wenige Millisekunden dauerten. Das war also erstmals eine gute Entschärfung der Situation.

Statistikdaten müssen natürlich auch gepflegt werden. Hier ging es im speziellen darum, dass das Benutzerverhalten gebunden an die Session, ermittelt wird um daraus wiederum Rückschlüsse für Optimierungen am Shopsystem zu gewinnen. Ganz salopp gesagt:

Wenn ein Kunde einen bestimmten Artikelstamm im Warenkorb hat, will er sich nicht durch x Menus klicken um das passende Zubehör dafür zu suchen. Kontext sensitive Navigation könnte man es nennen.

 Dabei handelt es sich jedoch nicht um Daten, die 1. sonderlich wichtig sind (im Vergleich zu Zahlungen z.B.), 2. werden diese auch nie sofort ausgewertet. Statt einer komplexen Datensammlung über die Datenbank wurde diese Funktion auf das Protokollieren der Sessiondaten in ein Logfile reduziert. Damit kam man immer noch an Suchbegriffe etc. heran. Der Rest findet sich im access_log des Webservers und kann darüber in Abgleich zu den Sessiondaten für Auswertungen zu Lastarmen Zeiten zusammen geführt werden. ggf. auch auf einer eigenen Umgebung.

Blieb also noch die Frage der Sessiondaten. Da es nunmal eine geclusterte Umgebung (Webanwendung) war, war das aufteilen der Sessiondaten auf einem Filesystem auf dem jeweils lokalen System nicht möglich. Die Appserver wurden aus Kostengründen nicht ans SAN angebunden und somit war keine schneller zentraler Storage gegeben. Die Sessiondaten wurden auch niemals sehr gross, sodass eine Auslagerung in die DB i.O. war. Hier allerdings war MyIsam ungeeignet wegen der hohen Schreibrate. Sessiondaten sind zwar ärgerlich, wenn sie verloren gehen, aber sind kein Weltuntergang. Entsprechend wurden die Sessiontabelle als Memory Table angelegt.

Das zumindest war der Erste Schritt, so dass ein Regelbetrieb wieder möglich war. Fortsetzung folgt.

PS: Ich habe selten Zeit zu dokumentieren, was ich im Falle eines "Feuerwehreinsatzes" exakt mache. Merken kann ich mir ohnehin nichts, weshalb es schwierig ist hinterher genau zu rekonstruieren, welche Befehle man eingegeben hat, welche Informationen man aufgenommen hat und was letztendlich für welche Besserung gesorgt hat. Deshalb ist eine genaue Erläuterung an konkreten Fällen sinnvoll, aber dafür braucht man Zeit und im Bezug unkritischen Referenz Fall. Ich selbst bin aber aus dem Studium, der Selbstfindungsphase sowie der Notwendigkeit mich am Markt zu etablieren längst heraus. Daher werde ich i.d.R. keine Bücher schreiben, keine Referenzumgebung aufbauen und Fälle nachstellen.Das gibt mir meine verfügbare Zeit ausserhalb eines erfüllten Arbeitslebens nicht her. Wer hingegen einen "Referenzfall" hätte, darf sich gerne melden, muss aber die nötige Geduld mit bringen, bis ich die Zeit finde mich darum zu kümmern.

Kategorien: IT

Noch keine Kommentare

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