Andreas Korthaus: "HTTP-Cache" für PHP-Applikation

Beitrag lesen

Hallo!

Ich versuche lediglich, so früh zu optimieren, wie eben möglich. Was habe ich davon erstmal zig Sachen zu laden, die Last verursachen, wenn ich dem Server diese Arbeit doch zum großen Teil ersparen kann?

Gegenfrage: Was habe ich davon, zig Sachen zu programmieren, wenn ich am Ende nicht merke, überhaupt etwas gemacht zu haben?

Oh, das merkt man durchaus wenn nur genügend User die Applikation gleichzeitig verwenden und die Antwortzeiten im Rahmen bleiben - und davon kann ich ausgehen.

Es ist eine Abwägung zwischen Komplexität und Geschwindigkeitsvorteil. Mir persönlich erscheint Deine Vorgehensweise viel zu aufwendig und -wichtiger- fehlerträchtig, relativ gesehen zum tatsächlichen, absoluten Geschwindigkeitsvorteil.

Was ist daran denn komplex? Die RewriteRule schreibe ich so einmal in die httpd.conf, dann wird die direkt beim Serverstart geladen, und ich mache maximal einen Rewrite, genau das mache ich heute auch schon, es kommen nur 3-4 Mustervergleiche dazu. Ich würde es liebend gerne testen, habe auch schon ein nettes Tool hierfür(M$ Web Application Stress Tool), jetzt brache ich nur noch die Testumgebung, leider habe ich da keine Möglichkeit vor Weihnachten. Würde gerne ein bisschen testen.

Jedenfalls muss ich nur einmal die RewriteRule anpassen, und dann nur noch in der Applikation dafür sorgen, dass die Cache-Dateien entsprechend erzeugt und gelöscht werden. Und hierfür würde ich eine Klasse entwickeln, mit entsprechenden Methoden die die ganze Arbeit übernehmen.

Im Prinzip würde ich das dann so verwenden:

$cache = new Cache;

// um die aktuelle Seite cachen zu lassen:
$cache->createCache();

// um bei Änderungen die Cache-Files von 2 anderen Scripten zu löschen:
$cache->clearCache($dir,$script,$query_string);
$cache->clearCache($dir,$script2,$query_string2);

Nur ist vor allem letzters kein gutes Design, da muss ich nochmal ein bisschen nachdenken wie ich das sauberer machen kann. Vielleicht müsste ich alle Caching-Scripte irgendwo zentral verwalten, udn könnte dann IDs... verwenden... mal sehen.

Die Klasse jedenfalls kümmert sich um den ganzen Rest. Und besonders aufwendig ist auch das nicht. Wenn ich jetzt davon ausgehe dass ich ca. 20 Scripte habe, die was an Daten verändern, und das ist auch meistens nicht sonderlich komplex so dass es vielleicht im Schnitt 1-2 Seiten sind, die von Änderungen die über dieses Script eingegeben wurden, betroffen sind. Und dann muss ich auch nicht alle Seiten cachen, bei manchen macht es mehr Sinn, bei manchen weniger. Wenn ich eine Seite nicht cache, ist das Risiko eines Fehlers durch mein Caching-Framework exakt === 0.

Und die "read-only" Seiten, die deutlich überwiegen, kann ich mit der kleinen Zeile oben ganz einfach cachen. Ganz ohne Parameter, die hole ich mir woanders her oder übergebe sie vorher(nicht im eigentlichen Script) an die Konstruktor-Funktion.

Man könnte die Geschichte auch noch auf die Spitze treiben und sagen, daß das, was Du an Personalkosten für Optimierungen verursachst, nie und nimmer auf der Hardwareseite eingespart werden kann.

Da sei Dir mal nicht so sicher, die Software ist keine Einzel-Installation (Außerdem weißt Du nicht wie wenig ich verdiene ;-)).

Außerdem finde ich es einfach interessant und mache das größtenteils in meiner Freizeit.

Wenn ich sehe dass mit (IMHO) halbwegs vergleichbaren Maßnahmen Einsparungen um den Faktor 10-50 realisiert werden, ist das für mich durchaus ein Gebiet, wo es sich löhnt mal drüber nachzudenken,

Faktoren sind relativ. 10 bis 50 sieht für sich alleine gut aus, zugegeben, aber ist das auch noch der Fall, wenn es um kokrete Zahlen geht, beispielsweise die Entscheidung zwischen 0.1 oder 5 Tausendstel Sekunden?

Das Problem sind weniger Antwortzeiten einzelner Requests, sondern die Gesamtlast zu Lastspitzen.

Und das insbesondere angesichts der Tatsache, daß das Programm nach dem 0.1 oder 5 Millisekunden-Start eine halbe Minute läuft, weil es soviele Daten verarbeiten muß?

Das verstehe ich jetzt nicht?!

verwende ich aber keine statische HTML-Seite, sondern nur einen File-System-Check und einen 304 Header, was sicher schneller ist als statisches HTML.

Nein, da befindest Du Dich nun wirklich auf dem Holzweg. Der Apache liest von ganz alleine die Dateiinfos und sendet dann gegebenenfalls ein Not Modified. Ausgelesen wird die Datei nur, wenn es wirklich sein muß.

Aber woher zum Henker weiß Dein Apache dass ich was in der DB geändert hat, was sich auf die Ausgabe auswirkt? Und wie regelt es der Apache dass er die Datei ggfs. von PHP aktualisieren lässt?

Bei einer statischen Datei betreibst Du also einen noch größeren Aufwand: Beide Varianten (Apache alleine sowie Apache plus Deine mod_rewrite-Konstruktion) prüfen das Änderungsdatum der Datei, Du bringst hingegen auch noch mod_rewrite ins Spiel.

Nein, nein, die Cache-Datei die ich erzeuge sind leer. Sie dienen einzig und alein als Infgormationsträger um aus mod_rewrite heraus in der Lage zu sein zu entscheiden ob 304-Header oder Script-Ausführung.

Interpretersysteme haben grundsätzlich den Nachteil, daß sie bei jeder Ausführung neu interpretiert, also in entsprechende Anweisungsblöcke für den Prozessor übersetzt werden müssen. Das gilt auch, wenn der Programmcode vorverarbeitet in einem Cache zwischengespeichert wird, denn auch hier muß immer noch eine Anweisungsliste umgesetzt werden. Dazu kommt, daß durch die Vereinfachung, die den meisten Interpretersprachen zu eigen ist, auf die Hardware abgestimmte Optimierungen nur schwerlich möglich sind.

Daher versuche ich diese ineffektiven Prozesse so weit wie möglich zu eliminieren, indem ich schon in der Apache-Konfiguration kläre iob die Daten aktuell sind oder nicht. Für den Fall dass sie aktuell sind - cache-Flag Datei vorhenden - dann wird ein 304-Header gesendet, sonst muss ich wohl oder übel den Interpreter bitten mit die Seite neu ztuammenzusetzen. Diese wird dann an den Client ausgeliefert der diese dann cached. gleichzeitig wird eine Cache-Flag Datei erzeugt anhand der der Apche beim nächsten Request weiß "aha, die Datei hat der Client schon lokal", also kann er mit 304 antworten.

Wo habe ich bitte geschrieben, daß PHP doof sei? Es gibt Anwendungsgebiete, auf denen ein System X einfach nicht mit einem System Y mithalten kann. Punkt, so ist das nunmal.

Ganz klar, siehe Forum, was das gebracht hat (wenn ich auch gerne mal im Vergleich eine mod_perl Variante sehen würde).
Aber INterpreter-Sprachen haben auch entscheidende Vorteile. Die Entwicklungs-Zeit ist erheblich kürzer, und es gibt gerade bei PHP sehr viele Bibliotheken, die einen Entwickler in eben solchen komplexen Web-Applikationen sehr gut unterstützen. Ich wolt emeien Anwendung nicht in C schreiben müssen...

Mit meiner Anmerkung "egal wie c00l" wollte ich in gewisser Hinsicht genau auf Deine obige Reaktion abzielen: Anstatt die Grenzen von PHP anzuerkennen wird dieses System auf Teufel komm raus verteidigt. Damit fällt man aber früher oder später auf die Nase.

Vollkommen richtig, nur halte ich PHP nach wie vor für die beste Sprache für Web-Applikationen, so lange es nicht zu groß oder zu komplex wird.

Und wenn Du aus PHP-Scripten HTML-Dateien erzeugst und zwischenspeicherst, dann ist das für mich auch eine Art des Caching.

Ja, richtig, und? Das habe ich doch eingangs als Alternative vorgeschlagen: Bei Änderung der Daten neue HTML-Dateien erstellen und die persönlichen Vorlieben (z.B. das Datumsformat) per Javascript außerhalb des Servers umsetzen.

Und wie mache ich das mit den GET-Parametern? EIn großer Vorteil ist ja, dass ich im Prinzip so jeden Request cachen kann.

Grüße
Andreas