Du bist nicht angemeldet (anmelden)
Seite 1
Erledigt: Bilder lokal auf dem Server „cachen“
Hallo zusammen,
ich hab schon seit längerem eine File-Listing Seite, die alle Dateien und Ordner eines Verzeichnisses anzeigt. In der aktuellen Version ist es u.a. möglich, vorschau Thumbnails von Bildern (und von pdfs) erzeugen zu lassen. Allerdings werden die Thumbnails momentan noch bei jedem Aufruf neu erzeugt, was beim ersten Aufruf, je nach Menge der Bilder, ziemlich auf die Ladezeiten geht.
Jetzt suche ich nach einer Möglichkeit, dass die Bilder lokal auf dem Server in einem nicht mitgelistetem Unterverzeichnis gechached werden können (bspw. .temp). Soweit kein Problem, allerdings müsste noch Überprüft werden, ob die Bilder sich geändert haben (auch nicht das große Problem), oder ob das Bild vom Server gelöscht wurde. Es macht ja keinen Sinn, Thumbnails von Bildern abgelegt zu haben, die schon vor Monaten gelöscht wurden. Das ganze möglichst Performance freundlich. Letzteres ist mit relativ viel Aufwand verbunden, zumindest so wie ich das sehe. Momentan habe ich die Ordnerstruktur für die Thumbnails wie folgt geplant:
Cronjobs kommen dabei nicht in Frage, da ich das ganze Variabel halten möchte (bis auf ein paar Ausnahmen ist alles „Lebenswichtige“ in einer Datei abgelegt). Und nicht jeder Server, auf dem man das einsetzen könnte, Ünterstützt Cronjobs.
Hat irgendwer eine Idee, wie man das lösen kann, ohne die Performance in den Keller zu ziehen? Oder denke ich einfach nur zu umständlich und es gibt noch eine viel einfachere Lösung?
(Nicht das es zu Missverständnissen kommt: Es geht hier nicht darum, dass die Bilder beim Benutzer gecached werden sollen, dass ist schon der Fall.)
ich hab schon seit längerem eine File-Listing Seite, die alle Dateien und Ordner eines Verzeichnisses anzeigt. In der aktuellen Version ist es u.a. möglich, vorschau Thumbnails von Bildern (und von pdfs) erzeugen zu lassen. Allerdings werden die Thumbnails momentan noch bei jedem Aufruf neu erzeugt, was beim ersten Aufruf, je nach Menge der Bilder, ziemlich auf die Ladezeiten geht.
Jetzt suche ich nach einer Möglichkeit, dass die Bilder lokal auf dem Server in einem nicht mitgelistetem Unterverzeichnis gechached werden können (bspw. .temp). Soweit kein Problem, allerdings müsste noch Überprüft werden, ob die Bilder sich geändert haben (auch nicht das große Problem), oder ob das Bild vom Server gelöscht wurde. Es macht ja keinen Sinn, Thumbnails von Bildern abgelegt zu haben, die schon vor Monaten gelöscht wurden. Das ganze möglichst Performance freundlich. Letzteres ist mit relativ viel Aufwand verbunden, zumindest so wie ich das sehe. Momentan habe ich die Ordnerstruktur für die Thumbnails wie folgt geplant:
testBild.jpg → .temp/thumbs/testBild.jpgAlso müsste man das komplette Verzeichnis „thumbs“ samt Unterordner durchscannen und schauen, ob (entsprechend der Unterordner) die zugehörigen Dateien noch existieren. Man könnte zwar auch hingehen und alle Thumbnails in einen Ordner packen, da besteht allerdings das Problem, dass man dann die Dateien so umbenennen müsste, dass es a) keine Überschreibungen gibt und b) die Zuordnung des entsprechenden Bildes + Unterordner noch gewährleistet ist.
unterordner/testBild → .temp/thumbs/unterordner/testBild.jpg
Cronjobs kommen dabei nicht in Frage, da ich das ganze Variabel halten möchte (bis auf ein paar Ausnahmen ist alles „Lebenswichtige“ in einer Datei abgelegt). Und nicht jeder Server, auf dem man das einsetzen könnte, Ünterstützt Cronjobs.
Hat irgendwer eine Idee, wie man das lösen kann, ohne die Performance in den Keller zu ziehen? Oder denke ich einfach nur zu umständlich und es gibt noch eine viel einfachere Lösung?
(Nicht das es zu Missverständnissen kommt: Es geht hier nicht darum, dass die Bilder beim Benutzer gecached werden sollen, dass ist schon der Fall.)
Dieser Text ist nur für Mitglieder sichtbar.
grad der „simpelste“ ansatz, der mir einfällt:
keine cronjobs, hohe performance, keine überlegungen mit ordnerstruktur, pseudocode.
pfad = /der/kompletteDateipfad/zum/Bild.jpgfunction getThumbPath( pfad )hashstr = irgendeineHashfunktion( pfad )extension = jpgif not exists ( thumbs/hashstr.extension )erzeuge thumb von Bild.jpg und lege es unter thumbs/hashstr.extension abreturn thumbs/hashstr.extension
keine cronjobs, hohe performance, keine überlegungen mit ordnerstruktur, pseudocode.
Okay, das wäre schonmal wesentlich einfacher, als ich momentan das Thumbnail abspeichern gebastelt hab (da musste ich zuerst den kompletten Pfad zerlegen und überprüfen, ob die Ordner schon existieren). Danke erstmal. 
Allerdings ist da das Problem, dass die Thumbnails gelöscht werden sollen, falls die jeweiligen Ursprungsbilder nicht mehr existieren, auch noch nicht gelöst.
Allerdings ist da das Problem, dass die Thumbnails gelöscht werden sollen, falls die jeweiligen Ursprungsbilder nicht mehr existieren, auch noch nicht gelöst.
Also müsste man das komplette Verzeichnis „thumbs“ samt Unterordner durchscannen und schauen, ob (entsprechend der Unterordner) die zugehörigen Dateien noch existieren.
das wäre die „perfekte“ Lösung, ja, aber einfacher wäre vl.:
bei jedem Aufruf sich nur eine Datei aus dem thumbs-Ordner vornehmen.
So würdest Du nach und nach auch Ordnung halten können.
Dem kommt noch zu gute, dass Dateien bei den meisten Galleries selten gelöscht werden.
Romanski schrieb am 08.12.08, 20:44 Uhr:
bei jedem Aufruf sich nur eine Datei aus dem thumbs-Ordner vornehmen.
So würdest Du nach und nach auch Ordnung halten können.
Da wäre allerdings das Problem, dass irgendwo vermerkt werden müsste, welche Stelle zuletzt betrachtet wurde. Wie ich aber bereits geschrieben hatte, will ich die „äußeren Einflüsse“ möglichst gering halten.
Dem kommt noch zu gute, dass Dateien bei den meisten Galleries selten gelöscht werden.
Das ist allerdings keine Gallerie, sondern (bei mir zumindest) eine Übersicht über meinen ganzen Müll, und da wird relativ viel gelöscht.
Zudem gehts einfach um das Prinzip: ich will nicht massenhaft Datenmüll von längst vergangenen Dateien rumfliegen haben.
Editiert: 08.12.08, 22:38 Uhr
stimmt, das mit dem löschen hatte ich großzügig überlesen.ich würde mir aber, wenn nicht unbedingt absolute aktualität beim löschen nötig ist, keinen stress machen mit beobachten wann was gelöscht werden kann, sondern einfach vor den hash eine zahl=verzeichnis knallen, die dadurch die lebenszeit (in etwa) bestimmt.
also enweder 2008-12 (monat) oder 2008-44 (woche) oder sowas...
und dann alle verzeichnisse ausser das aktuell gültige löschen lassen. und das vielleicht nicht bei jedem aufruf prüfen, sondern sagen wir mal nur zwischen 0 und 1 uhr oder so (auch wenns kein besucher ist, werden zumindest mal ein paar bots zu der zeit mal vorbeischauen. wahrscheinlich.)
sowas:
...derUnterordner = jahr-monat...wenn es zeit dazu ist:delete all folders ausser derUnterordnerreturn thumbs/derUnterordner/hashstr.extension
Da wäre allerdings das Problem, dass irgendwo vermerkt werden müsste, welche Stelle zuletzt betrachtet wurde. Wie ich aber bereits geschrieben hatte, will ich die „äußeren Einflüsse“ möglichst gering halten.
hm ne, ich meine: bei jedem Aufruf wählst du zufällig einen thumb-Datei aus und checkst, ob das Original dazu noch da ist. Alles zufällig, alles über die Zeit verteilt. So kann die Sache „langsam aber sicher“ gepflegt werden / sauber gehalten werden.
Warum löschst Du die Dateien nicht aus Deinem Script heraus und löschst bei dieser Aktion das zugehörige Thumb einfach mit? Oder die Holzammermethode: Thumb-Verzeichnis löschen, wann immer Dir nach Reinlichkeit ist.
moin,
das löst man in der regel ganz einfach:
die thumbs werden erst bei anforderung des bildes erzeugt, danach in das tmp verzeichnis abgelegt. 1x im monat (oder ein anderer intervall) wird das komplette tmp verzeichnis per cronjob gelöscht und somit ist man wieder auf stand null. die erfahrung zeigt ja, das ältere bilder seltener aufgerufen werden, also werden die evtl, nie wieder im cache stehen. da das ganze eh nur auf bildanforderung geschieht, spart man sich so speicher und berechnung von thumbs bei nicht mehr benötigten files.
man muss das für die meisten zwecke nicht unnötig kompliziert machen. willst du es kompliziert machen, dann brauchst du dahinter eine datenbank mit den bildnamen und pfaden, wo der hash des inhalts gespeichert wird - den vergleichst du dann mit dem hash im dateinamen des thumbs (weil ein thumb hat generiert einen anderen hash als das original). aber so weit must du nicht gehen. es kostet den server fast mehr zeit sich durch mehrere tausend dateien zu crawlen, einzulesen, hash zu bilden und zu vergleichen, als ein thumb bei bedarf neu zu erstellen.
das löst man in der regel ganz einfach:
die thumbs werden erst bei anforderung des bildes erzeugt, danach in das tmp verzeichnis abgelegt. 1x im monat (oder ein anderer intervall) wird das komplette tmp verzeichnis per cronjob gelöscht und somit ist man wieder auf stand null. die erfahrung zeigt ja, das ältere bilder seltener aufgerufen werden, also werden die evtl, nie wieder im cache stehen. da das ganze eh nur auf bildanforderung geschieht, spart man sich so speicher und berechnung von thumbs bei nicht mehr benötigten files.
man muss das für die meisten zwecke nicht unnötig kompliziert machen. willst du es kompliziert machen, dann brauchst du dahinter eine datenbank mit den bildnamen und pfaden, wo der hash des inhalts gespeichert wird - den vergleichst du dann mit dem hash im dateinamen des thumbs (weil ein thumb hat generiert einen anderen hash als das original). aber so weit must du nicht gehen. es kostet den server fast mehr zeit sich durch mehrere tausend dateien zu crawlen, einzulesen, hash zu bilden und zu vergleichen, als ein thumb bei bedarf neu zu erstellen.
Ich werds dann wohl so versuchen, dass in bestimmten Intervallen alle Thumbnails gelöscht werden. Allerdings nicht durch Cronjobs, da ich die wie bereits beschrieben, nicht einsetzen möchte.
Den thumbnail Ordner durchgehen und alle in Frage kommenden Dateien per unlink() löschen, oder gehts noch einfacher? rmdir() kann ja erst benutzt werden, wenn der Ordner auch leer ist.
Das ist jetzt auch schon der Fall. Wird index.php?thumbnail=Beispiel.jpg aufgerufen, wird jetzt erstmal überprüft, ob das Thumbnail bereits existiert und wenn dies der Fall ist, der Header auf das Bild umgeleitet.
Den thumbnail Ordner durchgehen und alle in Frage kommenden Dateien per unlink() löschen, oder gehts noch einfacher? rmdir() kann ja erst benutzt werden, wenn der Ordner auch leer ist.
stese schrieb am 09.12.08, 08:20 Uhr:
die thumbs werden erst bei anforderung des bildes erzeugt
Das ist jetzt auch schon der Fall. Wird index.php?thumbnail=Beispiel.jpg aufgerufen, wird jetzt erstmal überprüft, ob das Thumbnail bereits existiert und wenn dies der Fall ist, der Header auf das Bild umgeleitet.
//$thumbSrc = $_REQUEST['thumbnail'];$cacheDirectory = $tempDirectory."/thumbs/"; // $tempDirectory = ".temp"$file = $_SERVER["DOCUMENT_ROOT"].$path."/".$thumbSrc;if ($enableCache) {$hash = md5($thumbSrc);$thumbExt = fileExtension($thumbSrc);// [...]$hashFile = $hash.".".$thumbExt;if (!file_exists($cacheDirectory))if (!mkdir($cacheDirectory)) $enableCache = false;if (file_exists($cacheDirectory.$hashFile)) {if (filemtime($thumbSrc) <= filemtime($cacheDirectory.$hashFile)) {Header("Location: ".$cacheDirectory.$hashFile);die();}}}// Bild wird erzeugt
naja variabel is ja ok
bei servern, wo wir keine cronjobs verfügbar haben (in der firma nicht der fall) nutzen wir z.b. http://www.cronjob.de (
)
Das kommt aber auch eher weniger in Frage, da man bei Bedarf einfach nur die index.php (und optional noch jquery, thickbox etc) hochladen muss und schon ist das Teil einsatzbereit.
Werd mich die Tage mal dran setzen und schauen, ob das auch ohne Cronjob noch einigermaßen Performance freundlich läuft.
Bis hier hin schonmal danke.
Werd mich die Tage mal dran setzen und schauen, ob das auch ohne Cronjob noch einigermaßen Performance freundlich läuft.
Bis hier hin schonmal danke.
übrigens sowas hier macht man gar nicht (also die /), wenn du flexibelsein willst:
wenn du wirklich flexibel sein willst muss das auch einwandfrei unter windows IIS laufen. dafür gibts eine Systemkonstante DIRECTORY_SEPERATOR die je nach os entweder ein / oder \ liefert.
daneben kann man mkdir auc mit dem parameter „recursive“ aufrufen, der dir mehr als ein verzeichnis erstellt - eben so viele die du brauchst
tipp: um wirklich modifikationen der datei zu ermitteln, holst du dir z.b. einen md5 hash aus dem inhalt der datei und nicht nur aus dem dateinamen. ist da nur ein zeichenpaar vertauscht, ändert sich der md5 und somit garantierst du, dass der inhalt imer aktuell ist
noch nen tipp: wenn du vorhast sehr sehr viele dateien mit dem ding zu verwalten, dann separiere dir weitere temp unterverzeichnisse. ich habe mir angewöhnt vom dateinamen (in deinem fall der md5 hash) den ersten buchstaben zu nehmen und so ein unterverzeichnis zu erstellen, in dem die datei dann liegt, also: cachepath/6/6342897d98234ndsf87sdf6098sdf
hat den vorteil, dass die verzeichnisse nicht zu viele dateien beherbergen, die das system irgendwann ausbremsen und vor allem irgendwann zu fehlern führen. (wir haben gezwungenermaßen gerade ein projekt mit über 30.000 files in einem directory - es gibt den seltsamen fall, dass einige files, die drinn sind, nicht gefunden werden) - verschiedene dateizugriffsbefehle werden bei dieser menge auch unerträglich langsam (filepointer setzen beim lesen) und verbrauchen nen höllen speicher.
nächster tipp: wenn du die cache datei direkt rausheaderst, hast du das problem, dass robots und co diese cache datei indexieren. das umgehst du indem du mit readfile nur den inhalt des cachefiles liest - die url ändert sich damit nämlich nicht und du kannst „schön flexibel“ auch ab und an das cacheverzeichnis leeren, ohne dass querverlinkungen aufgetreten wären.
."/thumbs/" .
wenn du wirklich flexibel sein willst muss das auch einwandfrei unter windows IIS laufen. dafür gibts eine Systemkonstante DIRECTORY_SEPERATOR die je nach os entweder ein / oder \ liefert.
daneben kann man mkdir auc mit dem parameter „recursive“ aufrufen, der dir mehr als ein verzeichnis erstellt - eben so viele die du brauchst
tipp: um wirklich modifikationen der datei zu ermitteln, holst du dir z.b. einen md5 hash aus dem inhalt der datei und nicht nur aus dem dateinamen. ist da nur ein zeichenpaar vertauscht, ändert sich der md5 und somit garantierst du, dass der inhalt imer aktuell ist
noch nen tipp: wenn du vorhast sehr sehr viele dateien mit dem ding zu verwalten, dann separiere dir weitere temp unterverzeichnisse. ich habe mir angewöhnt vom dateinamen (in deinem fall der md5 hash) den ersten buchstaben zu nehmen und so ein unterverzeichnis zu erstellen, in dem die datei dann liegt, also: cachepath/6/6342897d98234ndsf87sdf6098sdf
hat den vorteil, dass die verzeichnisse nicht zu viele dateien beherbergen, die das system irgendwann ausbremsen und vor allem irgendwann zu fehlern führen. (wir haben gezwungenermaßen gerade ein projekt mit über 30.000 files in einem directory - es gibt den seltsamen fall, dass einige files, die drinn sind, nicht gefunden werden) - verschiedene dateizugriffsbefehle werden bei dieser menge auch unerträglich langsam (filepointer setzen beim lesen) und verbrauchen nen höllen speicher.
nächster tipp: wenn du die cache datei direkt rausheaderst, hast du das problem, dass robots und co diese cache datei indexieren. das umgehst du indem du mit readfile nur den inhalt des cachefiles liest - die url ändert sich damit nämlich nicht und du kannst „schön flexibel“ auch ab und an das cacheverzeichnis leeren, ohne dass querverlinkungen aufgetreten wären.
Editiert: 12.12.08, 21:32 Uhr
Okay, danke für die Tipps. stese schrieb am 09.12.08, 20:18 Uhr:Meines Wissens nach kann PHP unter Windows die Slashes automatisch umformen, ohne das man DIRECTORY_SEPERATOR einsetzt. Hatte zumindest bisher keine Probleme damit.
wenn du wirklich flexibel sein willst muss das auch einwandfrei unter windows IIS laufen. dafür gibts eine Systemkonstante DIRECTORY_SEPERATOR die je nach os entweder ein / oder liefert.
nächster tipp: wenn du die cache datei direkt rausheaderst, hast du das problem, dass robots und co diese cache datei indexieren. das umgehst du indem du mit readfile nur den inhalt des cachefiles liest - die url ändert sich damit nämlich nicht und du kannst „schön flexibel“ auch ab und an das cacheverzeichnis leeren, ohne dass querverlinkungen aufgetreten wären.Hatte das anfänglich auch über readfile() laufen, allerdings hatte ich zumindest den Eindruck, dass es Performance technisch mit header(„Location: xyz&ldquo
e: Eigentlich doch nicht, da die Thumbnails erst in den Einstellungen aktiviert werden müssen, das ganze beim Laden auf display: none; steht und erst durch JS angezeigt wird und wohl kein robot auf die Idee kommt, da irgendwas einzustellen.
Soo ich hab jetzt auch eine Lösung für das Löschen der Thumbnails hinbekommen.
Per scandir() lass ich den Thumb-Ordner (in dem ich jetzt, wie von stese beschrieben, die Thumbnails in Unterordner gepackt habe) in ein Array schreiben. Dann wähle ich Zufällig einen der Ordner aus, der darauf hin komplett gelöscht wird. Das ganze wiederholt sich jede Woche. Um zu Überprüfen, ob noch gelöscht werden muss oder nicht, habe ich im .temp Verzeichnis eine Datei abgelegt, die beim löschen bearbeitet wird. So muss muss nur noch geschaut werden, ob die Änderung an der Datei schon eine Woche/länger zurück liegt und das ganze Spiel beginnt von vorne.
Danke nochmals für die Hilfe.
Per scandir() lass ich den Thumb-Ordner (in dem ich jetzt, wie von stese beschrieben, die Thumbnails in Unterordner gepackt habe) in ein Array schreiben. Dann wähle ich Zufällig einen der Ordner aus, der darauf hin komplett gelöscht wird. Das ganze wiederholt sich jede Woche. Um zu Überprüfen, ob noch gelöscht werden muss oder nicht, habe ich im .temp Verzeichnis eine Datei abgelegt, die beim löschen bearbeitet wird. So muss muss nur noch geschaut werden, ob die Änderung an der Datei schon eine Woche/länger zurück liegt und das ganze Spiel beginnt von vorne.
Danke nochmals für die Hilfe.
