AllesMeins: Seiten Cachen - Macht das Sinn?

Hi,

mache mir gerade Gedanken wie ich eine möglichst gutes Template-System (so Performanceschonend wie möglich) bauen könnte. Meine Frage ist ob das, was ich mir da ausgedacht habe, Performance-Technick Sinn macht oder ob es noch verbesserbar ist.

Es gibt bei dieser Seite zahlreiche Unterseiten bei denen sich ein Großteil nicht ändert und nur kleine Teile dynamisch sein sollen. Deshalb bin ich auf folgendes System verfallen. Ich lasse die Seiten einmal von PHP generieren und speichere sie dann in einem Cache-Verzeichniss. Nun gibt es aber bei den meisten Seiten doch Teile, die dynamisch sind, ich kann also schwer die Seite komplett Cachen. Deshalb war meine Idee die gespeicherten Seiten in Teile zu zerlegen. In die erste Zeile einer solchen Datei würde ich einfache Steueranweisungen schreiben und abhängig davon die Seite verarbeiten. Eine Anweisung ist dann zum Beispiel ob die Seite noch geparsed werden soll oder ob sie statisch ist. Eine zweite Anweisung wäre ob noch weitere teile folgen. Also wenn ich eine Seite mit folgendem Format hätte:

INHALT
INHALT
INHALT
INHALT
Irgendwas dynamisches
INHALT
INHALT
INHALT

So würde ich sie in 3 Cache-Files zerlegen. Das erste enthält den Anfang mit der Anweisung "Nicht dynamisch" und "suche nach Nachfolger", also kann der Inhalt einfach blind rausgegeben werden. Zweite Datei enthält die Anweisungen "Dynamisch" und "suche nach Nachfolger", der Inhalt wird also geparsed und dann rausgegeben und die dritte enthält nur "nicht dynamisch" und wird wieder einfach so rausgehauen.
Ich müsste also 3 verschiedene Dateien im Dateisystem lesen, verringe aber den zu parsenden Teil deutlich. Macht es Sinn das so zu machen? Oder ist es sinnvoller das Stückeln zu lassen und einfach nur die Seiten zu cachen die wirklich statisch sind und alles andere komplett zu parsen (mit allen Konsequenzen)? Oder habe ich sonst irgendwelche Probleme in meinem Entwurf übersehen?

Viele Grüße

Marc

  1. Moin!

    mache mir gerade Gedanken wie ich eine möglichst gutes Template-System (so Performanceschonend wie möglich) bauen könnte. Meine Frage ist ob das, was ich mir da ausgedacht habe, Performance-Technick Sinn macht oder ob es noch verbesserbar ist.

    Wenn's dir um Performance geht: Meide dynamische Webseiten. :)

    Wobei der Rat auch ganz ohne Smiley funktioniert: Schreibe deine Webseiten statisch auf den Server und liefere sie von der Platte aus. Ist wunderbar performant - wenngleich etwas aufwendiger beim Generieren. Und nicht so gut geeignet, um wirklich dynamische Informationen (wie z.B. die Zahl der Besucher, die gerade "online" sind) zu integrieren (wobei: für genau diesen Zweck kann man auch statisch das Ergebnis einer Zufallszahl von 1 bis 10 einbauen ;) ).

    Alternativ: Meide Template-Engines. Die verbrauchen auch einen teilweise erheblichen Anteil an Performance alleine zum Parsen des Templates. PHP ist ja selbst eine immer weiter aufgebohrte Template-Engine. Wenn man sich strikt an Code-Trennung hält, kann man damit auch effizient und vernünftig Templates herstellen.

    Alternativ: Optimiere nichts, was du nicht messen kannst. Denn wenn du nicht weißt, ob deine Alternative, die du dir kompliziert ausgedacht hast, wirklich schneller ist, oder langsamer, kannst du die jeglichen Gehirnschmalz genausogut auch sparen.

    Du brauchst zunächst also erst einmal einen Meßmechanismus und Kriterien, die du messen und optimieren willst. Ohne diese ist jeglicher Optimierungsversuch sinnlos.

    So würde ich sie in 3 Cache-Files zerlegen. Das erste enthält den Anfang mit der Anweisung "Nicht dynamisch" und "suche nach Nachfolger", also kann der Inhalt einfach blind rausgegeben werden. Zweite Datei enthält die Anweisungen "Dynamisch" und "suche nach Nachfolger", der Inhalt wird also geparsed und dann rausgegeben und die dritte enthält nur "nicht dynamisch" und wird wieder einfach so rausgehauen.
    Ich müsste also 3 verschiedene Dateien im Dateisystem lesen, verringe aber den zu parsenden Teil deutlich. Macht es Sinn das so zu machen? Oder ist es sinnvoller das Stückeln zu lassen und einfach nur die Seiten zu cachen die wirklich statisch sind und alles andere komplett zu parsen (mit allen Konsequenzen)? Oder habe ich sonst irgendwelche Probleme in meinem Entwurf übersehen?

    Die Frage ist, was du optimieren willst. Ladezeit beim User? CPU-Zyklen? Festplattenzugriffe minimieren? Außerdem, wo der Flaschenhals sitzt. Und dann noch, welchen Systemeinfluß du nehmen kannst. Das Einrichten einer RAM-Disk beispielsweise wäre sicherlich für einige Dinge recht hilfreich und würde enormes Potential bieten, dürfte aber andererseits wohl nur bei komplettem Serverzugriff als Admin möglich sein.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. Hi,

      Wenn's dir um Performance geht: Meide dynamische Webseiten. :)

      Geht bei meinen Zielen leider nicht ;)

      Alternativ: Meide Template-Engines. Die verbrauchen auch einen teilweise erheblichen Anteil an Performance alleine zum Parsen des Templates.

      Genau aus diesem Grund hatte ich die Idee das ganze beim Cachen in Teile zu zerlegen. Solche die einfach so raus gegeben werden können, da es für die Template-Engine nichts mehr zu tun gibt (zum Beispiel Seiten die vom Nutzer einmal mit Inhalt bestückt wurden, von der Template-Engine in ein passendes Layout gepackt wurden und dann so gespeichert wurden) und die Teile die halt doch bei jedem Aufruf neu generiert werden müssen. Eben weil ich schon ein "komisches Gefühl" bei der Idee hatte die komplette Ausgabe mehrfach durchzurödeln zu müssen.

      PHP ist ja selbst eine immer weiter aufgebohrte Template-Engine. Wenn man sich strikt an Code-Trennung hält, kann man damit auch effizient und vernünftig Templates herstellen.

      Gut, aber den HTML-Code muss ich ja so oder so mindestens einmal lesen und einmal an den Output-Buffer senden. Es müsste also doch in jedem Fall effektiver sein das Cache-File zu lesen, erste Zeile auszuwerten und in den meisten Fällen ohne weitere Arbeit alles was danach kommt quasi blind an den Output-Buffer zu schieben.

      Die Frage ist, was du optimieren willst. Ladezeit beim User? CPU-Zyklen? Festplattenzugriffe minimieren?

      In erster Linie Datenbank-Zugriffe und CPU-Zeit.

      1. Moin!

        Alternativ: Meide Template-Engines. Die verbrauchen auch einen teilweise erheblichen Anteil an Performance alleine zum Parsen des Templates.

        Genau aus diesem Grund hatte ich die Idee das ganze beim Cachen in Teile zu zerlegen.

        ...und damit dann wieder eine Template-Engine zu basteln.

        Solche die einfach so raus gegeben werden können, da es für die Template-Engine nichts mehr zu tun gibt (zum Beispiel Seiten die vom Nutzer einmal mit Inhalt bestückt wurden, von der Template-Engine in ein passendes Layout gepackt wurden und dann so gespeichert wurden) und die Teile die halt doch bei jedem Aufruf neu generiert werden müssen. Eben weil ich schon ein "komisches Gefühl" bei der Idee hatte die komplette Ausgabe mehrfach durchzurödeln zu müssen.

        Speichere deine Seite z.B. als /index.php (Startseite), und schreibe dort hinein die statischen Teile als HTML, und den dynamischen Teil als PHP - meinetwegen auch recht simpel nur als include(), der dann eine separate Datei mit der nur auf die Dynamik an dieser Stelle reduzierten Code enthält.

        Das Problem dabei ist: Wenn du am statischen Teil, der für mehrere oder alle Seiten gilt, was änderst, bist zu gezwungen, alle statischen Seiten neu zu generieren. Das kann auch ziemlich aufwendig werden. Es spart dir zwar die andauernd vorkommenden Requests in die Datenbank, die sich nicht ändern (wobei die Datenbank sowas auch cachen kann), du handelst dir dabei aber Kopfschmerzen beim Dateigenerieren ein.

        Und bevor du einwenden willst, dass du ja nur die Seiten generieren mußt, die sich geändert haben: Vergiß es! Es ist vermutlich aufwendiger (mindestens hinsichtlich der zu erstellenden Auswahllogik, vermutlich aber auch hinsichtlich der dafür zu ermittelnden Informationen), herauszufiltern, ob eine Seite neu generiert werden muß, anstatt einfach pauschal alle Seiten zu generieren.

        Ich habe mal ein CMS geschrieben, welches einen zentralen Seitenpool und individuelle Seiten für viele Filialen eines Unternehmens verwalten sollte. Wenn keine individuelle Seite existiert, wird die allgemeine Seite verwendet. Die Generierung der gesamten Website (ca. 300 Filialen, je Filiale etwa 15 Seiten) dauerte mehr als 15 Minuten - und das mit Flatfile-Datenhaltung und allen erdenklichen Beschleunigungsmaßnahmen bei der Generierung. Und das ist schon extrem schnell gewesen, das System dürfte mehrere Megabyte pro Sekunde auf die Festplatte geschrieben haben.

        PHP ist ja selbst eine immer weiter aufgebohrte Template-Engine. Wenn man sich strikt an Code-Trennung hält, kann man damit auch effizient und vernünftig Templates herstellen.

        Gut, aber den HTML-Code muss ich ja so oder so mindestens einmal lesen und einmal an den Output-Buffer senden. Es müsste also doch in jedem Fall effektiver sein das Cache-File zu lesen, erste Zeile auszuwerten und in den meisten Fällen ohne weitere Arbeit alles was danach kommt quasi blind an den Output-Buffer zu schieben.

        Nein, das bestreite ich, solange du keine Meßergebnisse bringst. Warum ist es weniger effektiver, einfach eine simple PHP-Datei mit wenig PHP zu parsen und an den Browser zu schicken? Dein System muß eine PHP-Datei parsen, dann eine Cache-Datei öffnen, eine Zeile 1 interpretieren, den nachfolgenden Inhalt ausgeben, oder den nachfolgenden Inhalt evaluieren, und dann das ganze an den Browser schicken. Sieht irgendwie deutlich aufwendiger aus.

        Also bitte nachmessen, was schneller ist. Wenn du nicht messen kannst, kannst du nicht optimieren. Nur weil du GLAUBST, dass etwas schneller ist, muß das nicht wirklich so sein.

        Man kann beispielsweise auf die Idee kommen, statt grundsätzlich eine Datei einzulesen und zu verarbeiten, erstmal deren Veränderungsdatum zu prüfen und nur dann, wenn sie neuer ist als der letzte Stand, sie verarbeiten.

        Blöd nur, wenn das Prüfen des Datums länger dauert, als die Datei einfach immer zu verarbeiten. Been there, done that - have the t-shirt! Siehe oben mein CMS.

        Die Frage ist, was du optimieren willst. Ladezeit beim User? CPU-Zyklen? Festplattenzugriffe minimieren?

        In erster Linie Datenbank-Zugriffe und CPU-Zeit.

        Wie erwähnt: Datenbanken haben Caches, es ist also beim zweiten und dritten Zugriff auf die gleichen Daten schneller ein Ergebnis geholt. Und CPU-Zeit kannst du nur sparen, indem du tatsächlich weniger arbeitest.

        Die Frage ist aber, ob die CPU zu 100% ausgelastet ist. Denn wenn du durch die Optimierung statt 50% idle dann 52% idle produzierst, sparst du vielleicht ein wenig Strom - aber kein bißchen Zeit.

        Deshalb: Erstelle dir ein Meßwerkzeug, mit dem du feststellen kannst, ob deine angedachten Optimierungen tatsächlich einen Vorteil bringen, und wie groß dieser ist.

        Bedenke auch, dass die Bedienbarkeit des CMS für den Autor betrachtet werden muß. Was bringt es, wenn man als Besucher statt schnell jetzt sehr schnell an die Seiten kommt, wenn der Autor nach einer Änderung erst mal 5 Minuten lang Seiten generieren lassen muß, damit der Cache aktualisiert ist. Oder dass er eine gewisse Zeit warten muß, bis die Änderung online verfügbar ist. Manche CMS-Nutzer sind drauf angewiesen, dass Informationen garantiert zu einer bestimmten Zeit online sind - jede Verzögerung wäre schädlich (nur als Beispiel: Ad-hoc-Publizierungen von Aktiengesellschaften oder deren Geschäftsberichte haben gesetzlich vorgeschrieben "unverzüglich" zu erscheinen - und abgesehen davon ist es immer peinlich, wenn solche Infos dem Fachpublikum bzw. den Redakteuren erst verzögert zugänglich werden).

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hi,

          Das Problem dabei ist: Wenn du am statischen Teil, der für mehrere oder alle Seiten gilt, was änderst, bist zu gezwungen, alle statischen Seiten neu zu generieren.

          Ja, aber das ließe recht einfach lösen indem man die Seiten beim Ausliefern cachen lässt. Da müssen sie sowieso zusammengebaut werden und dann kann der Krams auch einfach wieder in den Cache geschrieben werden. Wenn sich dann wirklich was am statischen Teil ändert löscht man einfach die entsprechenden Dateien aus dem Cache und wartet bis die betreffende Seite erneut abgerufen wird. Es ist ja unnötig den Cache beim Ändern direkt wieder komplett zu befüllen sondern das kann ja gemacht werden, wenn die betreffende Seite zum ersten mal angefragt wird.

          Und bevor du einwenden willst, dass du ja nur die Seiten generieren mußt, die sich geändert haben: Vergiß es! Es ist vermutlich aufwendiger (mindestens hinsichtlich der zu erstellenden Auswahllogik, vermutlich aber auch hinsichtlich der dafür zu ermittelnden Informationen), herauszufiltern, ob eine Seite neu generiert werden muß, anstatt einfach pauschal alle Seiten zu generieren.

          Nein, denn es ist bei mir sehr streng definiert auf welche Seiten eine Änderung Auswirkungen hat. Generell gibt es zwei Fälle:
          a.) Es wird eine seite geändert, betrifft eine Seite
          b.) Es wird das design geändert, betrifft alle Seiten.

          Ich habe mal ein CMS geschrieben, welches einen zentralen Seitenpool und individuelle Seiten für viele Filialen eines Unternehmens verwalten sollte. Wenn keine individuelle Seite existiert, wird die allgemeine Seite verwendet. Die Generierung der gesamten Website (ca. 300 Filialen, je Filiale etwa 15 Seiten) dauerte mehr als 15 Minuten

          Wozu war es nötig alle Seiten auf einmal zu generieren? Hätte es nicht ausgereicht die Seiten nur dann zu generieren, wenn sie zum ersten mal abgerufen werden sollen?

          Nein, das bestreite ich, solange du keine Meßergebnisse bringst. Warum ist es weniger effektiver, einfach eine simple PHP-Datei mit wenig PHP zu parsen und an den Browser zu schicken? Dein System muß eine PHP-Datei parsen, dann eine Cache-Datei öffnen, eine Zeile 1 interpretieren, den nachfolgenden Inhalt ausgeben, oder den nachfolgenden Inhalt evaluieren, und dann das ganze an den Browser schicken. Sieht irgendwie deutlich aufwendiger aus.

          Schon ein bisschen unfairer Vergleich zwischen "einfach parsen" und das andere System total auseinandergenommen, oder?
          Einfach parsen ist auch: PHP Datei öffnen, statisches HTML an den Browser senden, PHP block parsen, include-Datei (und womöglich noch die Datenquelle) öffnen, lesen, parsen, ergebniss an den Browser schicken, weiteres HTML lesen, rausschicken, PHP-Block parsen, include-Datei öffnen usw.
          Und die PHP-Anweisungen sind deutlich aufwendiger.

          Ist ja nicht so als könnte PHP die grundlegenden Dinge wie "vom filesystem lesen, Datei durchgehen, weitere Dateien lesen usw." sich sparen. Deshalb sage ich ja, das ich keine großen Nachteile sehe, da PHP diese "lästigen" Arbeiten ja auch alle erledigen muss.

          Also bitte nachmessen, was schneller ist. Wenn du nicht messen kannst, kannst du nicht optimieren. Nur weil du GLAUBST, dass etwas schneller ist, muß das nicht wirklich so sein.

          Behaupte ich auch nicht. Aber um zu messen muss man bauen und vorm bauen frag ich doch lieber nach ob nicht irgendwer schon im Voraus einen dicken Konzeptionsfehler findet.
          Aber ich werde das dann wohl einfach mal ausprobieren. Irgendwelche Tipps wie ich am dümmsten messe, eine einfache Laufzeitberachtung wird es ja wohl kaum tun...

          Wie erwähnt: Datenbanken haben Caches, es ist also beim zweiten und dritten Zugriff auf die gleichen Daten schneller ein Ergebnis geholt.

          Funktioniert aber auch nur, wenn die Datenbank auf dem selben Rechner rödelt...

          Bedenke auch, dass die Bedienbarkeit des CMS für den Autor betrachtet werden muß. Was bringt es, wenn man als Besucher statt schnell jetzt sehr schnell an die Seiten kommt, wenn der Autor nach einer Änderung erst mal 5 Minuten lang Seiten generieren lassen muß, damit der Cache aktualisiert ist.

          Keine Frage. Ausliefern von nicht aktuellen Seiten ist definitiv inakzeptabel. Aber das wird auch nicht weiter passieren, da sich immer nur einzelne Seiten ändern lassen.

          Marc

          1. Moin!

            Das Problem dabei ist: Wenn du am statischen Teil, der für mehrere oder alle Seiten gilt, was änderst, bist zu gezwungen, alle statischen Seiten neu zu generieren.

            Ja, aber das ließe recht einfach lösen indem man die Seiten beim Ausliefern cachen lässt. Da müssen sie sowieso zusammengebaut werden und dann kann der Krams auch einfach wieder in den Cache geschrieben werden. Wenn sich dann wirklich was am statischen Teil ändert löscht man einfach die entsprechenden Dateien aus dem Cache und wartet bis die betreffende Seite erneut abgerufen wird. Es ist ja unnötig den Cache beim Ändern direkt wieder komplett zu befüllen sondern das kann ja gemacht werden, wenn die betreffende Seite zum ersten mal angefragt wird.

            Wie gesagt: Nachmessen, ob und wieviel das bringt, wäre schlau.

            Abgesehen davon: Ein Cache, den man nur manuell durch Löschen seiner Inhalte zur Aktualisierung bewegen kann, klingt in meinen Ohren nicht so Klasse.

            Und bevor du einwenden willst, dass du ja nur die Seiten generieren mußt, die sich geändert haben: Vergiß es! Es ist vermutlich aufwendiger (mindestens hinsichtlich der zu erstellenden Auswahllogik, vermutlich aber auch hinsichtlich der dafür zu ermittelnden Informationen), herauszufiltern, ob eine Seite neu generiert werden muß, anstatt einfach pauschal alle Seiten zu generieren.

            Nein, denn es ist bei mir sehr streng definiert auf welche Seiten eine Änderung Auswirkungen hat. Generell gibt es zwei Fälle:
            a.) Es wird eine seite geändert, betrifft eine Seite
            b.) Es wird das design geändert, betrifft alle Seiten.

            Dann sind Änderungen in der Navigation also Designänderungen? Oder verlinkst du nicht?

            Ich habe mal ein CMS geschrieben, welches einen zentralen Seitenpool und individuelle Seiten für viele Filialen eines Unternehmens verwalten sollte. Wenn keine individuelle Seite existiert, wird die allgemeine Seite verwendet. Die Generierung der gesamten Website (ca. 300 Filialen, je Filiale etwa 15 Seiten) dauerte mehr als 15 Minuten

            Wozu war es nötig alle Seiten auf einmal zu generieren? Hätte es nicht ausgereicht die Seiten nur dann zu generieren, wenn sie zum ersten mal abgerufen werden sollen?

            Weil eine Seite aus diversen Elementen besteht, die alle geändert sein könnten: Seiteninhalt der individuellen Seite, oder der allgemeinen Seite, oder der Navigation, oder des Templates, oder der Filialdaten (Adresse etc.).

            Hätte ich bei jedem einzelnen Element erst feststellen wollen, ob und wann es geändert wurde, ob dieses Datum neuer ist als das der bereits bestehenden Seite, und ob deshalb eine Neugenerierung erfolgen muß, hätte ich zwar viel Zeit beim Generieren eingespart, aber deutlich mehr Zeit beim Ermitteln der Daten verbraucht.

            Abgesehen davon hatte das System diverse Nebenbedingungen, die ich erfüllen mußte: IIS, ASP, kein Rewriting, alte existierende URLs auf ".html" usw.

            Nein, das bestreite ich, solange du keine Meßergebnisse bringst. Warum ist es weniger effektiver, einfach eine simple PHP-Datei mit wenig PHP zu parsen und an den Browser zu schicken? Dein System muß eine PHP-Datei parsen, dann eine Cache-Datei öffnen, eine Zeile 1 interpretieren, den nachfolgenden Inhalt ausgeben, oder den nachfolgenden Inhalt evaluieren, und dann das ganze an den Browser schicken. Sieht irgendwie deutlich aufwendiger aus.

            Schon ein bisschen unfairer Vergleich zwischen "einfach parsen" und das andere System total auseinandergenommen, oder?

            Nein, nicht wirklich. Ich habe verglichen, was an relevantem Unterschied passiert. So oder so muß eine PHP-Datei geöffnet und geparst werden. Entweder mit dem statischen und dynamischen Content, oder mit deinem Cachecode. Aber schätzungsweise ist es aufwendiger, erst den Code für das Feststellen des Cache-Falles auszuführen, dann den Cache einzulesen, die Inhalte aufzuspalten, den Dynamic-Teil durch eval() zu jagen und dann die Ausgabe an den Browser zu schicken, als einfach statisches HTML und PHP-Blöcke mit dem Minimum an Code zur Herstellung der Dynamik auszuführen - ohne innere eval()-Schicht und Cache-Parsing.

            Einfach parsen ist auch: PHP Datei öffnen, statisches HTML an den Browser senden, PHP block parsen, include-Datei (und womöglich noch die Datenquelle) öffnen, lesen, parsen, ergebniss an den Browser schicken, weiteres HTML lesen, rausschicken, PHP-Block parsen, include-Datei öffnen usw.

            Stimmt alles, aber deine Cache-Version wird ja wohl auch kaum um Includes herumkommen. Das dürfte also kaum einen Unterschied machen.

            Und die PHP-Anweisungen sind deutlich aufwendiger.

            Sofern die Dynamik erfordert, Kontakt zu einer Datenbank aufzunehmen, läßt sich das kaum wegrationalisieren. Damit ist allerdings auch ein zeitaufwendiger Faktor nicht zu eliminieren, nämlich der Connect zur DB.

            Also bitte nachmessen, was schneller ist. Wenn du nicht messen kannst, kannst du nicht optimieren. Nur weil du GLAUBST, dass etwas schneller ist, muß das nicht wirklich so sein.

            Behaupte ich auch nicht. Aber um zu messen muss man bauen und vorm bauen frag ich doch lieber nach ob nicht irgendwer schon im Voraus einen dicken Konzeptionsfehler findet.
            Aber ich werde das dann wohl einfach mal ausprobieren. Irgendwelche Tipps wie ich am dümmsten messe, eine einfache Laufzeitberachtung wird es ja wohl kaum tun...

            Das ist eben der Punkt: Wenn du messen willst, mußt du festlegen, was du messen willst. Also mußt du wissen, was du optimieren willst. Also mußt du wissen, wo der Schuh drückt.

            Und: Wo drückt der Schuh?

            Wie erwähnt: Datenbanken haben Caches, es ist also beim zweiten und dritten Zugriff auf die gleichen Daten schneller ein Ergebnis geholt.

            Funktioniert aber auch nur, wenn die Datenbank auf dem selben Rechner rödelt...

            Nein. Datenbanken haben immer Caches, und der Ort ihrer Werkels hat auf dessen Inhalt keinen Einfluß. Im Gegenteil: Ein eigenständiger DB-Server kann sich sogar mehr RAM für Caches genehmigen.

            Keine Frage. Ausliefern von nicht aktuellen Seiten ist definitiv inakzeptabel. Aber das wird auch nicht weiter passieren, da sich immer nur einzelne Seiten ändern lassen.

            Bis auf so Dinge wie Änderung von Navigation etc., die seitenübergreifend wirken. Da muß doch nur eine einzige Seite neu dazu kommen oder gelöscht werden, und schon kann auf der gesamten Site ein Link ungültig werden. Und sowas ist in aller Regel auch in den Bearbeitungsmöglichkeiten der Redakteure.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hi,

              Abgesehen davon: Ein Cache, den man nur manuell durch Löschen seiner Inhalte zur Aktualisierung bewegen kann, klingt in meinen Ohren nicht so Klasse.

              Wer redet von manuellem löschen?

              Dann sind Änderungen in der Navigation also Designänderungen? Oder verlinkst du nicht?

              Es sind zwar keine Design-Änderungen, aber es sind Änderungen die in die kategorie "b" fallen. Wird aber nicht oft vorkommen.

              Hätte ich bei jedem einzelnen Element erst feststellen wollen, ob und wann es geändert wurde, ob dieses Datum neuer ist als das der bereits bestehenden Seite, und ob deshalb eine Neugenerierung erfolgen muß, hätte ich zwar viel Zeit beim Generieren eingespart, aber deutlich mehr Zeit beim Ermitteln der Daten verbraucht.

              Klingt für mich eher nach magelnden Definitionen worauf sich Änderungen beziehen. Abgesehen davon würde ich sagen, das du einfach falsch rum denkst. Es ist nicht die Aufgabe des Systems bei jedem Abruf auf komplizierte Weise zu ermitteln ob was geändert wurde, sondern es sollte andersrum sein: Nämlich das ändernde System markiert (in irgend einer Form) die geänderten Seiten und erzwingt damit eine seitenweise neuberechnung, wenn eine solche Seite abgerufen werden soll. Alles andere ist meiner Meinung nach Unsinn.

              Abgesehen davon hatte das System diverse Nebenbedingungen, die ich erfüllen mußte: IIS, ASP, kein Rewriting, alte existierende URLs auf ".html" usw.

              Gut, das ist ein Problem deiner speziellen Situation aber kein Problem des allgemeinen Konzeptes.

              Nein, nicht wirklich. Ich habe verglichen, was an relevantem Unterschied passiert. So oder so muß eine PHP-Datei geöffnet und geparst werden. Entweder mit dem statischen und dynamischen Content, oder mit deinem Cachecode.

              Ja, aber bei deiner Lösung ist der zu parsende Code deutlich länger und komplexer. Das Cache-System selber wäre wahrscheinlich in ner Hand voll Zeilen zu realisieren.

              den Dynamic-Teil durch eval() zu jagen

              eval() ist böse! Wer macht denn sowas?

              Stimmt alles, aber deine Cache-Version wird ja wohl auch kaum um Includes herumkommen. Das dürfte also kaum einen Unterschied machen.

              Eben doch. Bzw. mit deutlich weniger auskommen da ja Teile der Programmlogik, die bei der simplen Version jedesmal ein include() und das einlesen einer Datenquelle erfordern würden, gar nicht mehr gebraucht werden sondern durch statische Ausgaben ersetzt wurden.

              Sofern die Dynamik erfordert, Kontakt zu einer Datenbank aufzunehmen, läßt sich das kaum wegrationalisieren.

              Erfordert sie aber nicht zwangsweise.

              Funktioniert aber auch nur, wenn die Datenbank auf dem selben Rechner rödelt...

              Nein. Datenbanken haben immer Caches, und der Ort ihrer Werkels hat auf dessen Inhalt keinen Einfluß.

              Ja, das ist schon klar. Ich meinte damit das dann die eigentliche Abfrage nicht mehr der potentielle Engpass ist sondern das zurückliefern der abgefragten Daten. Dann fallen Datenbankabfragen noch weit deutlicher ins Gewicht und der DB-Cache hilft da auch nichts, sondern nur das Vermeiden der Abfragen.

              Bis auf so Dinge wie Änderung von Navigation etc., die seitenübergreifend wirken. Da muß doch nur eine einzige Seite neu dazu kommen oder gelöscht werden, und schon kann auf der gesamten Site ein Link ungültig werden. Und sowas ist in aller Regel auch in den Bearbeitungsmöglichkeiten der Redakteure.

              In meinem Fall aber nicht ;)

              Marc

              1. hi,

                Abgesehen davon: Ein Cache, den man nur manuell durch Löschen seiner Inhalte zur Aktualisierung bewegen kann, klingt in meinen Ohren nicht so Klasse.

                Wer redet von manuellem löschen?

                Wenn du nicht "alles" neu generieren willst, brauchst du ein Entscheidungskriterium, _was_ du neu generieren willst.

                Du sprachst davon, die Seiten "beim Ausliefern" zu cachen.
                Primitivster Weg wäre: Wenn angeforderte Seite XY nicht physisch im Dateisystem vorhanden, dann stelle die Inhalte zusammen, liefere sie aus, und schreibe sie anschließend auf Platte, damit sie für den nächsten Zugriff "gecached" vorliegen.
                Nun musst du wegen einer Datenänderung neu generieren. Wenn es beim primitiven Mechanismus bleiben soll(!) - dann muss die physisch vorhandene Datei entfernt werden, da nur so eine Neugenerierung ausgelöst wird.

                Wenn das System "intelligenter" sein soll, dann kommst du an den Punkt, den Sven anspricht - du musst die Gültigkeit einer vorhandenen Cache-Version überprüfen. Das Erstellungsdatum könnte dabei ein Kriterium sein. Dann musst du dieses aber bei _jeder_ Auslieferung überprüfen - dein Cache-Mechanismus muss also zunächst mal das Dateisystem befragen, wie alt denn eigentlich Datei XY ist, bevor er sie entweder ausliest und an den Client durchschleust, oder sie neu generiert.

                Klingt für mich eher nach magelnden Definitionen worauf sich Änderungen beziehen.

                Hast du eine "bessere"?

                Abgesehen davon würde ich sagen, das du einfach falsch rum denkst. Es ist nicht die Aufgabe des Systems bei jedem Abruf auf komplizierte Weise zu ermitteln ob was geändert wurde, sondern es sollte andersrum sein: Nämlich das ändernde System markiert (in irgend einer Form) die geänderten Seiten und erzwingt damit eine seitenweise neuberechnung, wenn eine solche Seite abgerufen werden soll.

                Mit "in irgend einer Form" handelst du hier den Punkt, der dafür am wesentlichsten ist, recht banal ab.

                _Wie_ soll das gehen?

                Soll es Aufgabe des Daten einpflegenden Nutzers sein?
                Der weiß nicht unbedingt, wo sich die Änderung überall auswirkt,
                der vergisst betroffene Dokumente,
                der hat keine Lust, aus Dutzenden/Hunderten/... Dokumenten per Checkbox o.ä. die betroffenen auszuwählen.

                Oder soll im System "hinterlegt" sein, welche Änderung sich wo auswirken könnte?
                "Hinterlegt" in Anführungszeichen, weil auch das vermutlih nicht so trivial sein dürfte. Und wenn dein System hier zu viel Aufwand erzeugt, kommst du wieder an den von Sven angesprochenen Punkt, dass das System dem ändernden Nutzer zu viel Wartezeit abverlangt, bis seine Änderung wirksam wird.

                Ja, aber bei deiner Lösung ist der zu parsende Code deutlich länger und komplexer. Das Cache-System selber wäre wahrscheinlich in ner Hand voll Zeilen zu realisieren.

                Klar, oben angesprochenes "primitives" System sicherlich, auch mit zusätzlicher Überprüfung des Datums der Cache-Versionen.
                Nur stellt sich die Frage, wie performant und vor allem "besser" es dann noch wäre - wie gesagt, diese Überprüfung hätte bei _jeder_ Anfrage zu erfolgen, andernfalls lieferst du u.U. veraltete Daten aus.

                Stimmt alles, aber deine Cache-Version wird ja wohl auch kaum um Includes herumkommen. Das dürfte also kaum einen Unterschied machen.

                Eben doch. Bzw. mit deutlich weniger auskommen da ja Teile der Programmlogik, die bei der simplen Version jedesmal ein include() und das einlesen einer Datenquelle erfordern würden, gar nicht mehr gebraucht werden sondern durch statische Ausgaben ersetzt wurden.

                Wo kommen die "statischen Ausgaben" denn her, bzw. wo werden ihre Daten abgelegt?
                Das Dateisystem dürfte dafür vermutlich immer noch der vergleichsweise günstigste Ort sein, jedenfalls wenn wir sowas wie "RAM-Disk" mal aussen vor lassen.
                Also haben wir wieder Inhalte in Dateien, und diese müssen eingelesen werden. Ob du das jetzt "Include" nennst, oder bei reinen Datendateien sinnvollererweise in PHP eher readfile() benutzt, sei dahingestellt.

                Nein. Datenbanken haben immer Caches, und der Ort ihrer Werkels hat auf dessen Inhalt keinen Einfluß.

                Ja, das ist schon klar. Ich meinte damit das dann die eigentliche Abfrage nicht mehr der potentielle Engpass ist sondern das zurückliefern der abgefragten Daten. Dann fallen Datenbankabfragen noch weit deutlicher ins Gewicht und der DB-Cache hilft da auch nichts, sondern nur das Vermeiden der Abfragen.

                Auch wenn Webserver und DB-Server getrennte Maschinen sind, dürften sie im selben Rechenzentrum stehen, und untereinander ausreichend gut angebunden sein. Da sehe ich weniger einen Flaschenhals.

                gruß,
                wahsaga

                --
                /voodoo.css:
                #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. Hey,

    In die erste Zeile einer solchen Datei würde ich einfache Steueranweisungen schreiben und abhängig davon die Seite verarbeiten.

    Warnung: Metainformationen und Steuerdaten in-band zu übertragen ist fast immer ein Designfehler. Tu sie woanders hin.

    --
    水-金-地-火-木-土-天-海-冥
    1. Hi,

      Warnung: Metainformationen und Steuerdaten in-band zu übertragen ist fast immer ein Designfehler. Tu sie woanders hin.

      Ok, werde ich berücksichtigen. Aber wo liegt der Grund dafür?

      Grüße

      1. Meh, auf Anhieb finde ich nichts richtig Vernünftiges zur Untermauerung. Vielleicht http://c2.com/cgi/wiki?InBandSignal. Jedenfalls, wenn du die Steuerung seperat legst, kommst du mit einer Datei aus statt mehrerer verstreuter Schnippsel, und du öffnest die Fragmentdateien nur noch zum Durchreichen statt zum Analysieren des Inhalts, hier können ggf. diverse Hardware- und Softwarecache besser greifen.

        --
        水-金-地-火-木-土-天-海-冥
  3. n'abend,

    vor einiger Zeit habe ich einen OnlineShop geschrieben. Navigation (der Warengruppen), Artikellisten in Warengruppen und Artikelbeschreibungen sind Komponenten, die wild zusammengewürfelt die fertige Seite ergeben. Jede Komponente, von der ich ausging, dass sie auf mehreren Seiten eingebunden werden wird (z.B. Warengruppen-Navigation) wurde in einer sepparaten Datei gecached. Dies würde bedeutete an diesem Punkt zwar praktisch keine Datenbankzugriffe mehr, jedoch unzählige HDD-Zugriffe.

    Die fertige Seite (Artikeldetails) konnte nicht gecached werden, da für jeden Besucher ein anderer Inhalt im Warenkorb sein würde.

    Anstelle des Warenkorbs habe ich einen Platzhalter [insert_basket_here] in das Template geschrieben und die (fast fertige) Seite gecached. Beim Aufruf der seite wird nun nur noch der Inhalt des Warenkorbs ermittelt (Variable aus der Session lesen, Template öffnen, werte reinschieben) und das Warenkorbkonstrukt dann anstelle des [insert_basket_here] in die gecachete Datei gesetzt.

    Von multiplen Datenbankzugriffen und etlichen Dateisystemzugriffen bin ich also auf ein minimum herunter gekommen.

    ---
    Eine - der vielen - möglichen Herangehensweisen. Es kommt drauf an wie du deine Seiten strukturierst, was davon dynamisch bleiben muss, ob der restliche vermeindlich statische Kram es wert ist gecached zu werden, etc.

    weiterhin schönen abend...

    --
    wer braucht schon großbuchstaben?
    sh:( fo:# ch:# rl:° br:> n4:& ie:{ mo:} va:) de:] zu:} fl:{ ss:? ls:[ js:|