Extrem viele Scriptaufrufe

Valor

New Member
Hi Forum :)

ich hab mich hier angemeldet, da ich im Moment ein Problemchen habe und ein paar Ratschläge oder Tips bräuchte, wie ich damit umgehen soll.

Zunächst zum Problem:

Ich betreibe einen Server auf dem diverse Web-Foren (Honeypots zur Spambekämpfung) gehostet sind. Diese Foren werden wirklich extrem gut besucht, ich habe annähernd 10 Millionen Scriptcalls pro Tag. Soweit so gut... nun scheint jedoch irgendwo eine Grenze erreicht worden zu sein bei der ich auch mit Memcached und APC nicht mehr allzuviel reißen kann. Der Server verwendet Lighttpd und PHP-FastCGI. Es ist ein Linuxserver mit Debian Squeeze als System - 64 Bit.

Das Problem jetzt ist, dass die Seiten zwar immer noch ausgeliefert werden, allerdings teilweise mit bis zu 20 Sekunden Ladezeit. Der Server hat hierbei eine avg-Load von 4 bis 10 und einen Durchsatz von durchschnittlich 10-25 MBit/s.

Auch den MySQL-Server hab ich mittlerweile in eine ramdisk ausgelagert, damit der keine Disklast macht und die Ergebnisse möglichst rasant ausgeliefert werden. Der APC ist mit 512 MB bemessen und Memcached mit 256MB - ich komme hier auf 240 bis 600 Cache Requests pro Sekunde. Der Lighttpd wird mit max-procs "6" mit jeweils 5 Children und 2500 max-requests ausgeführt. KeepAlive wurde zu Testzwecken deaktiviert.

Hat hier wer eine Idee wie ich wieder eine performante Seitenauslieferung hinkriegen kann? Evtl ein anderer Cache oder sowas? Ich bin mittlerweile etwas ratlos, weil auch das Begegnen des Problems mit noch viel mehr möglichen Verbindungen nicht mehr geholfen hat.

Disklast, CPU- und Arbeitsspeicherauslastung ist an und für sich in einem relativ normalen Bereich noch - der Server hat eine Core i7 CPU (Quadcore, Hyperthreading) und 4 GB RAM. Ich würde nur gerne diese störenden Lags beheben können...
 
Last edited by a moderator:
Was sagt denn ein "ioping -i 0.1 -c 100" .?

Code:
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=1 time=14.6 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=2 time=117.6 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=3 time=2.1 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=4 time=8.4 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=5 time=3.7 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=6 time=31.4 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=7 time=9.2 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=8 time=65.7 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=9 time=18.0 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=10 time=32.7 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=11 time=33.8 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=12 time=57.7 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=13 time=9.6 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=14 time=0.3 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=15 time=35.3 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=16 time=0.2 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=17 time=34.0 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=18 time=34.0 ms
4096 bytes from . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d): request=19 time=3.9 ms
(... gekürzt)
--- . (ext4 /dev/disk/by-uuid/3a00b101-5bf4-4da2-b497-4ff4653b330d) ioping statistics ---
34 requests completed in 4166.2 ms, 40 iops, 0.2 mb/s
min/avg/max/mdev = 0.2/25.3/117.6/23.2 ms

Grundsätzlich Schwankungen von 0.2ms bis zu 44 ms...
 
Last edited by a moderator:
Jo hast recht, hatte in einem anderen Versuch nebenher wohl noch geschaut... aber worauf lassen diese Werte nun schließen? Zuviel IO-Last auf der Festplatte? Könnte wenns wäre auch die Web-Daten in eine ramdisk auslagern...
 
Wie wärs wenn du erstmal analysierst, womit er die 20 Sekunden Ladezeit überhaupt verbringt?
Wartet er vielleicht schon auf den Verbindungsaufbau oder ist der Webserver doch schon mit der Generierung der Seite beschäftigt?
Falls letzteres: Was macht der Webserver da 20 Sekunden lang? strace könnte hier helfen.
Ansonsten tcpdump/Wireshark.
 
Hast du Munin-Graphen (o.Ä.) von der CPU-Last bzw. wie diese sich zusammensetzt? Wäre hilfreich.
 
Bei dem was sich da Alles in den 4GB RAM tummelt, bleibt kaum noch Platz für MySQLs Temp-Tables, so dass diese erst mühsam on-disk geschrieben, verarbeitet und anschliessend gelöscht werden müssen. Das kostet ungemein Zeit, insbesondere wenn man aus den Zugriffszahlen die MySQL-Queries hochrechnet...

CPU-Last wird OK, aber RAM- und durch obige Annahme auch Disk-Last dürften am Limit sein.

RAM-Disks sind theoretisch gut, aber in der Praxis oft kontraproduktiv.


Mein Tipp: RAM-Disk(s) weg und ein aktuelles MySQL 5.5/5.6 InnoDB-only aufsetzen. Notfalls auf Percona umstellen.
 
Hallo,

Muningraphen hab ich nicht, da ich den Server nur mit Nagios auf den Grundzustand hin (Load, UP/DOWN, SSH aktiv, Mailqueue) überwache.

Strace-Abfragen sind leider auch kaum möglich, da ich sehr viele FastCGI-Prozesse offen hab und bei der riesigen Anzahl an Zugriffen die hereinkommt (>30 pro Sekunde etwa) so gut wie keine Chance besteht dass ich den richtigen erwische. Hab aber mal einen Abruf von Außen mittels Firebug nachvollzogen... der Firebug sagt mir dass die Seitenladezeit hauptsächlich durch Warten auf den Webserver zustandekommt.

Nachdem ich die Verbindungen vom Lighttpd noch weiter hochgedreht habe glaub ich aber nun die Ursache für dieses Problem gefunden zu haben:

Code:
2012-11-18 19:30:58: (mod_fastcgi.c.3001) backend is overloaded; we'll disable it for 1 seconds and send the request to another backend instead: reconnects: 0 load: 830

Soweit ich das verstehe ist hier der Lighttpd schon gnadenlos überlastet.

Nachdem nun das RAID-Rebuild auch noch angefangen hat sind die IO-Zeiten jetzt dementsprechend schlechter...

Glaube fast dass das alles nichts mehr hilft und ich wohl einen neuen Server bräuchte der den jetztigen unterstützt...

Nebenbei... InnoDB würde ich nur sehr ungern einsetzen wollen da ich hin und wieder Beschädigungen von Datenbanktabellen habe. Die Datenbanken werden grundsätzlich alle im 10-Minuten Takt auf "Factory Default" von phpbb3 z.B. zurückgesetzt, also alles herausgelöscht bis auf die wichtigen Konfigurationsdateien. Daher hab ich die auch in die Ramdisk verfrachtet, weil auch dort Temptables fix abgearbeitet werden sollten. Die Daten in den DBs sind völlig unwichtig, nur die Struktur muss erhalten bleiben, bei einem Totalausfall würde ich halt einfach ein Grundstrukturbackup einspielen und alles läuft wieder so wie es soll. Bei InnoDB kann ich leider kein REPAIR ausführen und eine Beschädigung von Tabellen führte jedes Mal zu einem Ausfall des MySQL-Servers. Dementsprechend bin ich InnoDBs gegenüber sehr skeptisch und setze sie nur dann ein wenn es wirklich gar keine andere Möglichkeit gibt.

Auf jeden Fall aber schonmal vielen Dank für die Tips und Anregungen die ich hier erhalten hab.
 
Last edited by a moderator:
Hallo,

ich habe mein Problem nun lösen können. Wollte nur nochmal hier posten wie ich das gemacht habe.

Ich habe nun einen Server mit 32 GB RAM bestellt und dort das System hinmigriert. Nun laufen die Mailqueue, MySQL (MyISAM only wg. maximaler Portabilität) und die gesamten Webinhalte in einer RAM-Disk.

Da mir bewusst ist, dass eine RAM-Disk leer ist wenn ich den Server reboote oder er abstürzt hab ich die Livedaten in ein TGZ-Archiv verfrachtet, also eine Grundstruktur der Datenbanken und alle PHP-Daten. Zudem wurde von der Ordnerstruktur des Postfix ein Backup gezogen und ein Script erstellt, welches die RAM-Disks nach dem Start wiederherstellt und alle Daten wieder draufkopiert.

Jetzt habe ich einige Millionen Scriptaufrufe täglich bei einer Load von maximal 0.20, Auslieferungszeiten von unter 500 ms und noch 16 GB RAM zur Verfügung (der Rest ist durch den Webserver und die RAM-Disks ausgelastet).

Läuft super!

Vielen Dank für eure Tips. Ein Upgrade zu MySQL5.6 werde ich demnächst in Angriff nehmen. InnoDB only geht allerdings deswegen schon nicht weil ich viel an Datenbankdaten hot kopiere. Wenn ich das mit InnoDB mache crasht mir das Ding sofort.
 
Last edited by a moderator:
Back
Top