[PHP] Cachingsystem für sehr viele Seiten



  • Hallo zusammen!

    Ich arbeite derzeit an einem Cachingsystem für eine Webseite mit vielen tausend einzelnen Seiten.

    Ich schreibe die Seiten sobald sie ein mal generiert wurden in Cachedateien ins Dateisystem. Wird die Seite erneut aufgerufen wird überprüft ob eine Cache-Datei vorliegt, wenn ja wird diese einfach ausgegeben.

    Nun habe ich ein Problem mit der Aktualisierung des Caches.
    Da es sehr viele Seite sind, und die Berechnung jeweils relativ aufwendig ist, möchte ich nur so selten wie möglich etwas neu berechnen. Daher sollen die Dateien nur aktualisiert werden, wenn sich irgendwas auf der Seite verändert hat, und nicht, wie man oft sieht, nach einer bestimmten Zeit (60 Minuten oder einem Tag).

    Derzeit ist es so gelöst, dass ich einfach die Cachedateien lösche, wenn sich etwas ändert. Als ich dies so aufbaute hatte ich dabei vergessen, dass es online wirklich sehr viele Seiten sind.

    Ich denke tausende Aufrufe von unlink() könnten innerhalb der normalen Ausführungszeit eines Scripts problematisch werden, oder?

    Da viele Seiten gegenseitig auf sich verweisen ist es praktisch nicht möglich festzustellen welche Seiten in Konsequenz einer Änderung eines Eintrags wirklich verändert wurden. (besser gesagt die zugrunde liegenden Daten in der Datenbank)

    Daher dachte ich an eine andere Lösung. Ich möchte eine Tabelle erstellen, in der für jede Seite ein Eintrag mit einem eindeutigen Kennzeichner (md5 aus URL) und einem Timestamp drin steht. Wenn die Cachedatei älter als der Timestamp ist wird die jeweilige Datei aktualisiert. Dann würde ich statt einige tausend Dateien zu löschen einfach die Tabelle leeren bzw. die Timestamps aktualisieren.

    Aber ich befürchte, dass es langsam sein wird eine Tabelle mit mehreren tausend Einträgen nach einem bestimmten md5-String zu "durchsuchen" um den Timestamp zu überprüfen. Oder irre ich mich da?

    Ich weiß derzeit einfach nicht, was die beste, d.h. effizienteste Lösung ist.
    Kann mir jemand eine Empfehlung aussprechen oder hat eine andere Idee für mich?

    Vielen Dank im Voraus für eure Antworten.
    (Entschuldigt den langen Text)



  • Hi MAG,

    bei so vielen Seiten frage ich mich erstmal, ob hier Cachen überhaupt einen Sinn macht. Es ist da nützlich, wo die Ausgabe sich nicht oft ändert und auf dieselbe Ausgabe oft zugegriffen wird; ansonsten ist das Quatsch, denn dynamische Seiten sollen doch dynamisch und flexibel bleiben. Diese Komplexität bei vielen gecachten Seiten heißt mehr oder weniger Rechenaufwand auf anderer Stelle, im dümmsten Fall schafft man sich praktisch eine zweite Datenbank und die Ausführungszeit steigt wo möglich noch an.

    Gruß Borschtsch


  • Mod

    das durchsuchen ist nicht so problematisch mit indeces sind tabellen da schon sehr sehr schnell.

    aber ich denke du hast, egal was du machst ein problem wenn der cache invalidiert wird: du hast dann einen load spike auf den server weil er plötzlich den kompletten cache aktualisiert.

    wenn es dir aber nur um das invalidieren des chachs geht: unlink() auf das directory, sollte problemlos schnell gehen. sollte sich aber leicht messen lassen.

    was aber uU interessanter ist, wäre eine langsame löschung des cachs. man schickt den usern vielleicht 5minuten (je nachdem was das für eine anwendung ist) alte daten und leert den cache in dieser zeit schrittweise langsam. der vorteil ist, dass man einen load spike bekommt unter dem der server eingeht.

    das ist zB auch der Vorteil der X Minuten caches.

    Die Frage die man sich eventuell stellen sollte: kommt das löschen des Caches so oft vor, dass das invalidieren des Cachs bereits ein Performance Problem ist. Wenn ja, dann sollte man uU eine andere caching strategie nehmen.



  • Aber ich befürchte, dass es langsam sein wird eine Tabelle mit mehreren tausend Einträgen nach einem bestimmten md5-String zu "durchsuchen" um den Timestamp zu überprüfen.

    Das ist wirklich kein Problem für jede Datenbank. Du solltest dann auch die angesprochenen Indizes verwenden, somit sollte das absolut performant sein. Mehrere tausend Einträge sind eigentlich gar nix für ne Datenbank.



  • Vielen Dank für eure Antworten!

    Die Ausgabe ändert sich nicht all zu oft, man kann von Tagen sprechen, in denen keine Änderungen vorgenommen werden. Beim Cache geht es mir auch nur um das löschen der Cachedateien, also wie Shade of Mine es vermutete, nur um das invalidieren.
    Die Seiten an sich werden dann jeweils beim Aufruf generiert, d.h. erst wenn die Seite erneut angefordert wird.

    Ich werde beide Möglichkeiten mal ausprobieren und versuchen festzustellen welche der beiden Varianten die effizientere ist.



  • Benutz ASP.NET, da geht es von selbst und es gibt keinen Frickel-Code.


Anmelden zum Antworten